summaryrefslogtreecommitdiffstats
path: root/3rdparty/assimp/code
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/assimp/code')
-rw-r--r--3rdparty/assimp/code/3DSConverter.cpp845
-rw-r--r--3rdparty/assimp/code/3DSHelper.h577
-rw-r--r--3rdparty/assimp/code/3DSLoader.cpp1376
-rw-r--r--3rdparty/assimp/code/3DSLoader.h280
-rw-r--r--3rdparty/assimp/code/ACLoader.cpp856
-rw-r--r--3rdparty/assimp/code/ACLoader.h271
-rw-r--r--3rdparty/assimp/code/ASELoader.cpp1302
-rw-r--r--3rdparty/assimp/code/ASELoader.h208
-rw-r--r--3rdparty/assimp/code/ASEParser.cpp2150
-rw-r--r--3rdparty/assimp/code/ASEParser.h669
-rw-r--r--3rdparty/assimp/code/Assimp.cpp731
-rw-r--r--3rdparty/assimp/code/AssimpPCH.cpp70
-rw-r--r--3rdparty/assimp/code/AssimpPCH.h149
-rw-r--r--3rdparty/assimp/code/B3DImporter.cpp672
-rw-r--r--3rdparty/assimp/code/B3DImporter.h126
-rw-r--r--3rdparty/assimp/code/BVHLoader.cpp505
-rw-r--r--3rdparty/assimp/code/BVHLoader.h173
-rw-r--r--3rdparty/assimp/code/BaseImporter.cpp527
-rw-r--r--3rdparty/assimp/code/BaseImporter.h499
-rw-r--r--3rdparty/assimp/code/BaseProcess.cpp96
-rw-r--r--3rdparty/assimp/code/BaseProcess.h289
-rw-r--r--3rdparty/assimp/code/BlenderDNA.cpp372
-rw-r--r--3rdparty/assimp/code/BlenderDNA.h798
-rw-r--r--3rdparty/assimp/code/BlenderDNA.inl706
-rw-r--r--3rdparty/assimp/code/BlenderIntermediate.h183
-rw-r--r--3rdparty/assimp/code/BlenderLoader.cpp1003
-rw-r--r--3rdparty/assimp/code/BlenderLoader.h261
-rw-r--r--3rdparty/assimp/code/BlenderModifier.cpp311
-rw-r--r--3rdparty/assimp/code/BlenderModifier.h155
-rw-r--r--3rdparty/assimp/code/BlenderScene.cpp596
-rw-r--r--3rdparty/assimp/code/BlenderScene.h683
-rw-r--r--3rdparty/assimp/code/BlenderSceneGen.h223
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/LICENSE_1_0.txt24
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/foreach.hpp93
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/format.hpp81
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp23
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/math/common_factor_rt.hpp37
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/pointer_cast.hpp45
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/scoped_array.hpp79
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/scoped_ptr.hpp79
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/shared_array.hpp228
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/shared_ptr.hpp257
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/static_assert.hpp20
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/timer.hpp82
-rw-r--r--3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp285
-rw-r--r--3rdparty/assimp/code/ByteSwap.h245
-rw-r--r--3rdparty/assimp/code/COBLoader.cpp1278
-rw-r--r--3rdparty/assimp/code/COBLoader.h175
-rw-r--r--3rdparty/assimp/code/COBScene.h284
-rw-r--r--3rdparty/assimp/code/CSMLoader.cpp281
-rw-r--r--3rdparty/assimp/code/CSMLoader.h88
-rw-r--r--3rdparty/assimp/code/CalcTangentsProcess.cpp283
-rw-r--r--3rdparty/assimp/code/CalcTangentsProcess.h118
-rw-r--r--3rdparty/assimp/code/ColladaHelper.h601
-rw-r--r--3rdparty/assimp/code/ColladaLoader.cpp1487
-rw-r--r--3rdparty/assimp/code/ColladaLoader.h241
-rw-r--r--3rdparty/assimp/code/ColladaParser.cpp2796
-rw-r--r--3rdparty/assimp/code/ColladaParser.h341
-rw-r--r--3rdparty/assimp/code/ComputeUVMappingProcess.cpp504
-rw-r--r--3rdparty/assimp/code/ComputeUVMappingProcess.h149
-rw-r--r--3rdparty/assimp/code/ConvertToLHProcess.cpp318
-rw-r--r--3rdparty/assimp/code/ConvertToLHProcess.h169
-rw-r--r--3rdparty/assimp/code/DXFLoader.cpp609
-rw-r--r--3rdparty/assimp/code/DXFLoader.h184
-rw-r--r--3rdparty/assimp/code/DefaultIOStream.cpp139
-rw-r--r--3rdparty/assimp/code/DefaultIOStream.h133
-rw-r--r--3rdparty/assimp/code/DefaultIOSystem.cpp167
-rw-r--r--3rdparty/assimp/code/DefaultIOSystem.h83
-rw-r--r--3rdparty/assimp/code/DefaultLogger.cpp419
-rw-r--r--3rdparty/assimp/code/DefaultProgressHandler.h64
-rw-r--r--3rdparty/assimp/code/Exceptional.h122
-rw-r--r--3rdparty/assimp/code/FileLogStream.h64
-rw-r--r--3rdparty/assimp/code/FileSystemFilter.h244
-rw-r--r--3rdparty/assimp/code/FindDegenerates.cpp216
-rw-r--r--3rdparty/assimp/code/FindDegenerates.h110
-rw-r--r--3rdparty/assimp/code/FindInstancesProcess.cpp288
-rw-r--r--3rdparty/assimp/code/FindInstancesProcess.h140
-rw-r--r--3rdparty/assimp/code/FindInvalidDataProcess.cpp419
-rw-r--r--3rdparty/assimp/code/FindInvalidDataProcess.h111
-rw-r--r--3rdparty/assimp/code/FixNormalsStep.cpp176
-rw-r--r--3rdparty/assimp/code/FixNormalsStep.h96
-rw-r--r--3rdparty/assimp/code/GenFaceNormalsProcess.cpp138
-rw-r--r--3rdparty/assimp/code/GenFaceNormalsProcess.h88
-rw-r--r--3rdparty/assimp/code/GenVertexNormalsProcess.cpp228
-rw-r--r--3rdparty/assimp/code/GenVertexNormalsProcess.h118
-rw-r--r--3rdparty/assimp/code/GenericProperty.h112
-rw-r--r--3rdparty/assimp/code/HMPFileData.h134
-rw-r--r--3rdparty/assimp/code/HMPLoader.cpp497
-rw-r--r--3rdparty/assimp/code/HMPLoader.h159
-rw-r--r--3rdparty/assimp/code/HalfLifeFileData.h150
-rw-r--r--3rdparty/assimp/code/Hash.h108
-rw-r--r--3rdparty/assimp/code/IFF.h102
-rw-r--r--3rdparty/assimp/code/IRRLoader.cpp1462
-rw-r--r--3rdparty/assimp/code/IRRLoader.h312
-rw-r--r--3rdparty/assimp/code/IRRMeshLoader.cpp499
-rw-r--r--3rdparty/assimp/code/IRRMeshLoader.h99
-rw-r--r--3rdparty/assimp/code/IRRShared.cpp496
-rw-r--r--3rdparty/assimp/code/IRRShared.h115
-rw-r--r--3rdparty/assimp/code/Importer.cpp1415
-rw-r--r--3rdparty/assimp/code/ImproveCacheLocality.cpp378
-rw-r--r--3rdparty/assimp/code/ImproveCacheLocality.h102
-rw-r--r--3rdparty/assimp/code/JoinVerticesProcess.cpp401
-rw-r--r--3rdparty/assimp/code/JoinVerticesProcess.h105
-rw-r--r--3rdparty/assimp/code/LWOAnimation.cpp582
-rw-r--r--3rdparty/assimp/code/LWOAnimation.h336
-rw-r--r--3rdparty/assimp/code/LWOBLoader.cpp396
-rw-r--r--3rdparty/assimp/code/LWOFileData.h699
-rw-r--r--3rdparty/assimp/code/LWOLoader.cpp1403
-rw-r--r--3rdparty/assimp/code/LWOLoader.h490
-rw-r--r--3rdparty/assimp/code/LWOMaterial.cpp898
-rw-r--r--3rdparty/assimp/code/LWSLoader.cpp885
-rw-r--r--3rdparty/assimp/code/LWSLoader.h242
-rw-r--r--3rdparty/assimp/code/LimitBoneWeightsProcess.cpp204
-rw-r--r--3rdparty/assimp/code/LimitBoneWeightsProcess.h146
-rw-r--r--3rdparty/assimp/code/LineSplitter.h217
-rw-r--r--3rdparty/assimp/code/MD2FileData.h163
-rw-r--r--3rdparty/assimp/code/MD2Loader.cpp414
-rw-r--r--3rdparty/assimp/code/MD2Loader.h126
-rw-r--r--3rdparty/assimp/code/MD2NormalTable.h217
-rw-r--r--3rdparty/assimp/code/MD3FileData.h315
-rw-r--r--3rdparty/assimp/code/MD3Loader.cpp1043
-rw-r--r--3rdparty/assimp/code/MD3Loader.h331
-rw-r--r--3rdparty/assimp/code/MD4FileData.h218
-rw-r--r--3rdparty/assimp/code/MD5Loader.cpp725
-rw-r--r--3rdparty/assimp/code/MD5Loader.h194
-rw-r--r--3rdparty/assimp/code/MD5Parser.cpp471
-rw-r--r--3rdparty/assimp/code/MD5Parser.h460
-rw-r--r--3rdparty/assimp/code/MDCFileData.h199
-rw-r--r--3rdparty/assimp/code/MDCLoader.cpp472
-rw-r--r--3rdparty/assimp/code/MDCLoader.h132
-rw-r--r--3rdparty/assimp/code/MDCNormalTable.h299
-rw-r--r--3rdparty/assimp/code/MDLDefaultColorMap.h118
-rw-r--r--3rdparty/assimp/code/MDLFileData.h959
-rw-r--r--3rdparty/assimp/code/MDLLoader.cpp1929
-rw-r--r--3rdparty/assimp/code/MDLLoader.h460
-rw-r--r--3rdparty/assimp/code/MDLMaterialLoader.cpp823
-rw-r--r--3rdparty/assimp/code/MS3DLoader.cpp646
-rw-r--r--3rdparty/assimp/code/MS3DLoader.h158
-rw-r--r--3rdparty/assimp/code/MakeVerboseFormat.cpp218
-rw-r--r--3rdparty/assimp/code/MakeVerboseFormat.h106
-rw-r--r--3rdparty/assimp/code/MaterialSystem.cpp612
-rw-r--r--3rdparty/assimp/code/MaterialSystem.h246
-rw-r--r--3rdparty/assimp/code/MemoryIOWrapper.h181
-rw-r--r--3rdparty/assimp/code/NDOLoader.cpp289
-rw-r--r--3rdparty/assimp/code/NDOLoader.h116
-rw-r--r--3rdparty/assimp/code/NFFLoader.cpp1256
-rw-r--r--3rdparty/assimp/code/NFFLoader.h216
-rw-r--r--3rdparty/assimp/code/OFFLoader.cpp211
-rw-r--r--3rdparty/assimp/code/OFFLoader.h96
-rw-r--r--3rdparty/assimp/code/ObjFileData.h324
-rw-r--r--3rdparty/assimp/code/ObjFileImporter.cpp521
-rw-r--r--3rdparty/assimp/code/ObjFileImporter.h136
-rw-r--r--3rdparty/assimp/code/ObjFileMtlImporter.cpp294
-rw-r--r--3rdparty/assimp/code/ObjFileMtlImporter.h115
-rw-r--r--3rdparty/assimp/code/ObjFileParser.cpp664
-rw-r--r--3rdparty/assimp/code/ObjFileParser.h137
-rw-r--r--3rdparty/assimp/code/ObjTools.h220
-rw-r--r--3rdparty/assimp/code/OgreImporter.cpp873
-rw-r--r--3rdparty/assimp/code/OgreImporter.h143
-rw-r--r--3rdparty/assimp/code/OgreImporterMaterial.cpp255
-rw-r--r--3rdparty/assimp/code/OgreXmlHelper.h79
-rw-r--r--3rdparty/assimp/code/OptimizeGraph.cpp347
-rw-r--r--3rdparty/assimp/code/OptimizeGraph.h147
-rw-r--r--3rdparty/assimp/code/OptimizeMeshes.cpp243
-rw-r--r--3rdparty/assimp/code/OptimizeMeshes.h187
-rw-r--r--3rdparty/assimp/code/ParsingUtils.h181
-rw-r--r--3rdparty/assimp/code/PlyLoader.cpp1050
-rw-r--r--3rdparty/assimp/code/PlyLoader.h174
-rw-r--r--3rdparty/assimp/code/PlyParser.cpp919
-rw-r--r--3rdparty/assimp/code/PlyParser.h501
-rw-r--r--3rdparty/assimp/code/PretransformVertices.cpp711
-rw-r--r--3rdparty/assimp/code/PretransformVertices.h166
-rw-r--r--3rdparty/assimp/code/ProcessHelper.h564
-rw-r--r--3rdparty/assimp/code/Profiler.h97
-rw-r--r--3rdparty/assimp/code/Q3BSPFileData.h228
-rw-r--r--3rdparty/assimp/code/Q3BSPFileImporter.cpp731
-rw-r--r--3rdparty/assimp/code/Q3BSPFileImporter.h110
-rw-r--r--3rdparty/assimp/code/Q3BSPFileParser.cpp272
-rw-r--r--3rdparty/assimp/code/Q3BSPFileParser.h89
-rw-r--r--3rdparty/assimp/code/Q3BSPZipArchive.cpp196
-rw-r--r--3rdparty/assimp/code/Q3BSPZipArchive.h182
-rw-r--r--3rdparty/assimp/code/Q3DLoader.cpp600
-rw-r--r--3rdparty/assimp/code/Q3DLoader.h135
-rw-r--r--3rdparty/assimp/code/RawLoader.cpp312
-rw-r--r--3rdparty/assimp/code/RawLoader.h123
-rw-r--r--3rdparty/assimp/code/RemoveComments.cpp108
-rw-r--r--3rdparty/assimp/code/RemoveComments.h88
-rw-r--r--3rdparty/assimp/code/RemoveRedundantMaterials.cpp204
-rw-r--r--3rdparty/assimp/code/RemoveRedundantMaterials.h107
-rw-r--r--3rdparty/assimp/code/RemoveVCProcess.cpp328
-rw-r--r--3rdparty/assimp/code/RemoveVCProcess.h123
-rw-r--r--3rdparty/assimp/code/SGSpatialSort.cpp169
-rw-r--r--3rdparty/assimp/code/SGSpatialSort.h139
-rw-r--r--3rdparty/assimp/code/SMDLoader.cpp1129
-rw-r--r--3rdparty/assimp/code/SMDLoader.h420
-rw-r--r--3rdparty/assimp/code/STLLoader.cpp398
-rw-r--r--3rdparty/assimp/code/STLLoader.h119
-rw-r--r--3rdparty/assimp/code/SceneCombiner.cpp1133
-rw-r--r--3rdparty/assimp/code/SceneCombiner.h365
-rw-r--r--3rdparty/assimp/code/ScenePreprocessor.cpp281
-rw-r--r--3rdparty/assimp/code/ScenePreprocessor.h116
-rw-r--r--3rdparty/assimp/code/SkeletonMeshBuilder.cpp267
-rw-r--r--3rdparty/assimp/code/SkeletonMeshBuilder.h122
-rw-r--r--3rdparty/assimp/code/SmoothingGroups.h103
-rw-r--r--3rdparty/assimp/code/SmoothingGroups.inl138
-rw-r--r--3rdparty/assimp/code/SortByPTypeProcess.cpp405
-rw-r--r--3rdparty/assimp/code/SortByPTypeProcess.h88
-rw-r--r--3rdparty/assimp/code/SpatialSort.cpp342
-rw-r--r--3rdparty/assimp/code/SpatialSort.h170
-rw-r--r--3rdparty/assimp/code/SplitLargeMeshes.cpp677
-rw-r--r--3rdparty/assimp/code/SplitLargeMeshes.h216
-rw-r--r--3rdparty/assimp/code/StandardShapes.cpp502
-rw-r--r--3rdparty/assimp/code/StandardShapes.h196
-rw-r--r--3rdparty/assimp/code/StdOStreamLogStream.h52
-rw-r--r--3rdparty/assimp/code/StreamReader.h385
-rw-r--r--3rdparty/assimp/code/StringComparison.h217
-rw-r--r--3rdparty/assimp/code/Subdivision.cpp589
-rw-r--r--3rdparty/assimp/code/Subdivision.h124
-rw-r--r--3rdparty/assimp/code/TargetAnimation.cpp246
-rw-r--r--3rdparty/assimp/code/TargetAnimation.h179
-rw-r--r--3rdparty/assimp/code/TerragenLoader.cpp252
-rw-r--r--3rdparty/assimp/code/TerragenLoader.h107
-rw-r--r--3rdparty/assimp/code/TextureTransform.cpp563
-rw-r--r--3rdparty/assimp/code/TextureTransform.h225
-rw-r--r--3rdparty/assimp/code/TinyFormatter.h141
-rw-r--r--3rdparty/assimp/code/TriangulateProcess.cpp401
-rw-r--r--3rdparty/assimp/code/TriangulateProcess.h98
-rw-r--r--3rdparty/assimp/code/UnrealLoader.cpp426
-rw-r--r--3rdparty/assimp/code/UnrealLoader.h204
-rw-r--r--3rdparty/assimp/code/ValidateDataStructure.cpp968
-rw-r--r--3rdparty/assimp/code/ValidateDataStructure.h187
-rw-r--r--3rdparty/assimp/code/Vertex.h301
-rw-r--r--3rdparty/assimp/code/VertexTriangleAdjacency.cpp132
-rw-r--r--3rdparty/assimp/code/VertexTriangleAdjacency.h124
-rw-r--r--3rdparty/assimp/code/Win32DebugLogStream.h50
-rw-r--r--3rdparty/assimp/code/XFileHelper.h200
-rw-r--r--3rdparty/assimp/code/XFileImporter.cpp672
-rw-r--r--3rdparty/assimp/code/XFileImporter.h159
-rw-r--r--3rdparty/assimp/code/XFileParser.cpp1434
-rw-r--r--3rdparty/assimp/code/XFileParser.h162
-rw-r--r--3rdparty/assimp/code/aiAssert.cpp68
-rw-r--r--3rdparty/assimp/code/assbin_chunks.h196
-rw-r--r--3rdparty/assimp/code/fast_atof.h306
-rw-r--r--3rdparty/assimp/code/irrXMLWrapper.h131
-rw-r--r--3rdparty/assimp/code/makefile111
-rw-r--r--3rdparty/assimp/code/makefile.mingw105
-rw-r--r--3rdparty/assimp/code/pstdint.h729
-rw-r--r--3rdparty/assimp/code/qnan.h110
-rw-r--r--3rdparty/assimp/code/res/assimp.rc80
-rw-r--r--3rdparty/assimp/code/res/resource.h14
250 files changed, 0 insertions, 91199 deletions
diff --git a/3rdparty/assimp/code/3DSConverter.cpp b/3rdparty/assimp/code/3DSConverter.cpp
deleted file mode 100644
index f4bd56f1..00000000
--- a/3rdparty/assimp/code/3DSConverter.cpp
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the 3ds importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "3DSLoader.h"
-#include "TargetAnimation.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Setup final material indices, generae a default material if necessary
-void Discreet3DSImporter::ReplaceDefaultMaterial()
-{
-
- // Try to find an existing material that matches the
- // typical default material setting:
- // - no textures
- // - diffuse color (in grey!)
- // NOTE: This is here to workaround the fact that some
- // exporters are writing a default material, too.
- unsigned int idx = 0xcdcdcdcd;
- for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
- {
- std::string s = mScene->mMaterials[i].mName;
- for (std::string::iterator it = s.begin(); it != s.end(); ++it)
- *it = ::tolower(*it);
-
- if (std::string::npos == s.find("default"))continue;
-
- if (mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.g ||
- mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.b)continue;
-
- if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 )
- {
- continue;
- }
- idx = i;
- }
- if (0xcdcdcdcd == idx)idx = (unsigned int)mScene->mMaterials.size();
-
- // now iterate through all meshes and through all faces and
- // find all faces that are using the default material
- unsigned int cnt = 0;
- for (std::vector<D3DS::Mesh>::iterator
- i = mScene->mMeshes.begin();
- i != mScene->mMeshes.end();++i)
- {
- for (std::vector<unsigned int>::iterator
- a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end();++a)
- {
- // NOTE: The additional check seems to be necessary,
- // some exporters seem to generate invalid data here
- if (0xcdcdcdcd == (*a))
- {
- (*a) = idx;
- ++cnt;
- }
- else if ( (*a) >= mScene->mMaterials.size())
- {
- (*a) = idx;
- DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material");
- ++cnt;
- }
- }
- }
- if (cnt && idx == mScene->mMaterials.size())
- {
- // We need to create our own default material
- D3DS::Material sMat;
- sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
- sMat.mName = "%%%DEFAULT";
- mScene->mMaterials.push_back(sMat);
-
- DefaultLogger::get()->info("3DS: Generating default material");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
-void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
-{
- for (std::vector< D3DS::Face >::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end();++i)
- {
- // check whether all indices are in range
- for (unsigned int a = 0; a < 3;++a)
- {
- if ((*i).mIndices[a] >= sMesh.mPositions.size())
- {
- DefaultLogger::get()->warn("3DS: Vertex index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
- }
- if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size())
- {
- DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate out unique verbose format representation
-void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh)
-{
- // TODO: really necessary? I don't think. Just a waste of memory and time
- // to do it now in a separate buffer.
-
- // Allocate output storage
- std::vector<aiVector3D> vNew (sMesh.mFaces.size() * 3);
- std::vector<aiVector3D> vNew2;
- if (sMesh.mTexCoords.size())
- vNew2.resize(sMesh.mFaces.size() * 3);
-
- for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size();++i)
- {
- D3DS::Face& face = sMesh.mFaces[i];
-
- // Positions
- for (unsigned int a = 0; a < 3;++a,++base)
- {
- vNew[base] = sMesh.mPositions[face.mIndices[a]];
- if (sMesh.mTexCoords.size())
- vNew2[base] = sMesh.mTexCoords[face.mIndices[a]];
-
- face.mIndices[a] = base;
- }
- }
- sMesh.mPositions = vNew;
- sMesh.mTexCoords = vNew2;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS texture to texture keys in an aiMaterial
-void CopyTexture(MaterialHelper& mat, D3DS::Texture& texture, aiTextureType type)
-{
- // Setup the texture name
- aiString tex;
- tex.Set( texture.mMapName);
- mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
-
- // Setup the texture blend factor
- if (is_not_qnan(texture.mTextureBlend))
- mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
-
- // Setup the texture mapping mode
- mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
- mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
-
- // Mirroring - double the scaling values
- // FIXME: this is not really correct ...
- if (texture.mMapMode == aiTextureMapMode_Mirror)
- {
- texture.mScaleU *= 2.f;
- texture.mScaleV *= 2.f;
- texture.mOffsetU /= 2.f;
- texture.mOffsetV /= 2.f;
- }
-
- // Setup texture UV transformations
- mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS material to an aiMaterial
-void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
- MaterialHelper& mat)
-{
- // NOTE: Pass the background image to the viewer by bypassing the
- // material system. This is an evil hack, never do it again!
- if (0 != mBackgroundImage.length() && bHasBG)
- {
- aiString tex;
- tex.Set( mBackgroundImage);
- mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
-
- // Be sure this is only done for the first material
- mBackgroundImage = std::string("");
- }
-
- // At first add the base ambient color of the scene to the material
- oldMat.mAmbient.r += mClrAmbient.r;
- oldMat.mAmbient.g += mClrAmbient.g;
- oldMat.mAmbient.b += mClrAmbient.b;
-
- aiString name;
- name.Set( oldMat.mName);
- mat.AddProperty( &name, AI_MATKEY_NAME);
-
- // Material colors
- mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // Phong shininess and shininess strength
- if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
- D3DS::Discreet3DS::Metal == oldMat.mShading)
- {
- if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength)
- {
- oldMat.mShading = D3DS::Discreet3DS::Gouraud;
- }
- else
- {
- mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
- mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
- }
- }
-
- // Opacity
- mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
-
- // Bump height scaling
- mat.AddProperty<float>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
-
- // Two sided rendering?
- if (oldMat.mTwoSided)
- {
- int i = 1;
- mat.AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
- }
-
- // Shading mode
- aiShadingMode eShading = aiShadingMode_NoShading;
- switch (oldMat.mShading)
- {
- case D3DS::Discreet3DS::Flat:
- eShading = aiShadingMode_Flat; break;
-
- // I don't know what "Wire" shading should be,
- // assume it is simple lambertian diffuse shading
- case D3DS::Discreet3DS::Wire:
- {
- // Set the wireframe flag
- unsigned int iWire = 1;
- mat.AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- case D3DS::Discreet3DS::Gouraud:
- eShading = aiShadingMode_Gouraud; break;
-
- // assume cook-torrance shading for metals.
- case D3DS::Discreet3DS::Phong :
- eShading = aiShadingMode_Phong; break;
-
- case D3DS::Discreet3DS::Metal :
- eShading = aiShadingMode_CookTorrance; break;
-
- // FIX to workaround a warning with GCC 4 who complained
- // about a missing case Blinn: here - Blinn isn't a valid
- // value in the 3DS Loader, it is just needed for ASE
- case D3DS::Discreet3DS::Blinn :
- eShading = aiShadingMode_Blinn; break;
- }
- mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
-
- // DIFFUSE texture
- if ( oldMat.sTexDiffuse.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexDiffuse, aiTextureType_DIFFUSE);
-
- // SPECULAR texture
- if ( oldMat.sTexSpecular.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexSpecular, aiTextureType_SPECULAR);
-
- // OPACITY texture
- if ( oldMat.sTexOpacity.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexOpacity, aiTextureType_OPACITY);
-
- // EMISSIVE texture
- if ( oldMat.sTexEmissive.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexEmissive, aiTextureType_EMISSIVE);
-
- // BUMP texture
- if ( oldMat.sTexBump.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexBump, aiTextureType_HEIGHT);
-
- // SHININESS texture
- if ( oldMat.sTexShininess.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS);
-
- // REFLECTION texture
- if ( oldMat.sTexReflective.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexReflective, aiTextureType_REFLECTION);
-
- // Store the name of the material itself, too
- if ( oldMat.mName.length()) {
- aiString tex;
- tex.Set( oldMat.mName);
- mat.AddProperty( &tex, AI_MATKEY_NAME);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Split meshes by their materials and generate output aiMesh'es
-void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
-{
- std::vector<aiMesh*> avOutMeshes;
- avOutMeshes.reserve(mScene->mMeshes.size() * 2);
-
- unsigned int iFaceCnt = 0,num = 0;
- aiString name;
-
- // we need to split all meshes by their materials
- for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i) {
- boost::scoped_array< std::vector<unsigned int> > aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
-
- name.length = ASSIMP_itoa10(name.data,num++);
-
- unsigned int iNum = 0;
- for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end();++a,++iNum)
- {
- aiSplit[*a].push_back(iNum);
- }
- // now generate submeshes
- for (unsigned int p = 0; p < mScene->mMaterials.size();++p)
- {
- if (aiSplit[p].empty()) {
- continue;
- }
- aiMesh* meshOut = new aiMesh();
-
- std::string name_parts((*i).mName);
- name_parts.append("::");
- name_parts.append(mScene->mMaterials.at(p).mName);
-
- meshOut->mName.Set(name_parts);
- meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // be sure to setup the correct material index
- meshOut->mMaterialIndex = p;
-
- // use the color data as temporary storage
- meshOut->mColors[0] = (aiColor4D*)(&*i);
- avOutMeshes.push_back(meshOut);
-
- // convert vertices
- meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
- meshOut->mNumVertices = meshOut->mNumFaces*3;
-
- // allocate enough storage for faces
- meshOut->mFaces = new aiFace[meshOut->mNumFaces];
- iFaceCnt += meshOut->mNumFaces;
-
- meshOut->mVertices = new aiVector3D[meshOut->mNumVertices];
- meshOut->mNormals = new aiVector3D[meshOut->mNumVertices];
- if ((*i).mTexCoords.size())
- {
- meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices];
- }
- for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
- {
- register unsigned int index = aiSplit[p][q];
- aiFace& face = meshOut->mFaces[q];
-
- face.mIndices = new unsigned int[3];
- face.mNumIndices = 3;
-
- for (unsigned int a = 0; a < 3;++a,++base)
- {
- unsigned int idx = (*i).mFaces[index].mIndices[a];
- meshOut->mVertices[base] = (*i).mPositions[idx];
- meshOut->mNormals [base] = (*i).mNormals[idx];
-
- if ((*i).mTexCoords.size())
- meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx];
-
- face.mIndices[a] = base;
- }
- }
- }
- }
-
- // Copy them to the output array
- pcOut->mNumMeshes = (unsigned int)avOutMeshes.size();
- pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes]();
- for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) {
- pcOut->mMeshes[a] = avOutMeshes[a];
- }
-
- // We should have at least one face here
- if (!iFaceCnt) {
- throw DeadlyImportError("No faces loaded. The mesh is empty");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a node to the scenegraph and setup its final transformation
-void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
- D3DS::Node* pcIn, aiMatrix4x4& /* absTrafo */)
-{
- std::vector<unsigned int> iArray;
- iArray.reserve(3);
-
- aiMatrix4x4 abs;
-
- // Find all meshes with the same name as the node
- for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a)
- {
- const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0];
- ai_assert(NULL != pcMesh);
-
- if (pcIn->mName == pcMesh->mName)
- iArray.push_back(a);
- }
- if (!iArray.empty())
- {
- // The matrix should be identical for all meshes with the
- // same name. It HAS to be identical for all meshes .....
- D3DS::Mesh* imesh = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0]);
-
- // Compute the inverse of the transformation matrix to move the
- // vertices back to their relative and local space
- aiMatrix4x4 mInv = imesh->mMat, mInvTransposed = imesh->mMat;
- mInv.Inverse();mInvTransposed.Transpose();
- aiVector3D pivot = pcIn->vPivot;
-
- pcOut->mNumMeshes = (unsigned int)iArray.size();
- pcOut->mMeshes = new unsigned int[iArray.size()];
- for (unsigned int i = 0;i < iArray.size();++i) {
- const unsigned int iIndex = iArray[i];
- aiMesh* const mesh = pcSOut->mMeshes[iIndex];
-
- // Transform the vertices back into their local space
- // fixme: consider computing normals after this, so we don't need to transform them
- const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
- aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals;
-
- for (;pvCurrent != pvEnd;++pvCurrent,++t2) {
- *pvCurrent = mInv * (*pvCurrent);
- *t2 = mInvTransposed * (*t2);
- }
-
- // Handle negative transformation matrix determinant -> invert vertex x
- if (imesh->mMat.Determinant() < 0.0f)
- {
- /* we *must* have normals */
- for (pvCurrent = mesh->mVertices,t2 = mesh->mNormals;pvCurrent != pvEnd;++pvCurrent,++t2) {
- pvCurrent->x *= -1.f;
- t2->x *= -1.f;
- }
- DefaultLogger::get()->info("3DS: Flipping mesh X-Axis");
- }
-
- // Handle pivot point
- if (pivot.x || pivot.y || pivot.z)
- {
- for (pvCurrent = mesh->mVertices;pvCurrent != pvEnd;++pvCurrent) {
- *pvCurrent -= pivot;
- }
- }
-
- // Setup the mesh index
- pcOut->mMeshes[i] = iIndex;
- }
- }
-
- // Setup the name of the node
- pcOut->mName.Set(pcIn->mName);
-
- // Now build the transformation matrix of the node
- // ROTATION
- if (pcIn->aRotationKeys.size()){
-
- // FIX to get to Assimp's quaternion conventions
- for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
- (*it).mValue.w *= -1.f;
- }
-
- pcOut->mTransformation = aiMatrix4x4( pcIn->aRotationKeys[0].mValue.GetMatrix() );
- }
- else if (pcIn->aCameraRollKeys.size())
- {
- aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(- pcIn->aCameraRollKeys[0].mValue),
- pcOut->mTransformation);
- }
-
- // SCALING
- aiMatrix4x4& m = pcOut->mTransformation;
- if (pcIn->aScalingKeys.size())
- {
- const aiVector3D& v = pcIn->aScalingKeys[0].mValue;
- m.a1 *= v.x; m.b1 *= v.x; m.c1 *= v.x;
- m.a2 *= v.y; m.b2 *= v.y; m.c2 *= v.y;
- m.a3 *= v.z; m.b3 *= v.z; m.c3 *= v.z;
- }
-
- // TRANSLATION
- if (pcIn->aPositionKeys.size())
- {
- const aiVector3D& v = pcIn->aPositionKeys[0].mValue;
- m.a4 += v.x;
- m.b4 += v.y;
- m.c4 += v.z;
- }
-
- // Generate animation channels for the node
- if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 ||
- pcIn->aScalingKeys.size() > 1 || pcIn->aCameraRollKeys.size() > 1 ||
- pcIn->aTargetPositionKeys.size() > 1)
- {
- aiAnimation* anim = pcSOut->mAnimations[0];
- ai_assert(NULL != anim);
-
- if (pcIn->aCameraRollKeys.size() > 1)
- {
- DefaultLogger::get()->debug("3DS: Converting camera roll track ...");
-
- // Camera roll keys - in fact they're just rotations
- // around the camera's z axis. The angles are given
- // in degrees (and they're clockwise).
- pcIn->aRotationKeys.resize(pcIn->aCameraRollKeys.size());
- for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size();++i)
- {
- aiQuatKey& q = pcIn->aRotationKeys[i];
- aiFloatKey& f = pcIn->aCameraRollKeys[i];
-
- q.mTime = f.mTime;
-
- // FIX to get to Assimp quaternion conventions
- q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD( /*-*/ f.mValue));
- }
- }
-#if 0
- if (pcIn->aTargetPositionKeys.size() > 1)
- {
- DefaultLogger::get()->debug("3DS: Converting target track ...");
-
- // Camera or spot light - need to convert the separate
- // target position channel to our representation
- TargetAnimationHelper helper;
-
- if (pcIn->aPositionKeys.empty())
- {
- // We can just pass zero here ...
- helper.SetFixedMainAnimationChannel(aiVector3D());
- }
- else helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
- helper.SetTargetAnimationChannel(&pcIn->aTargetPositionKeys);
-
- // Do the conversion
- std::vector<aiVectorKey> distanceTrack;
- helper.Process(&distanceTrack);
-
- // Now add a new node as child, name it <ourName>.Target
- // and assign the distance track to it. This is that the
- // information where the target is and how it moves is
- // not lost
- D3DS::Node* nd = new D3DS::Node();
- pcIn->push_back(nd);
-
- nd->mName = pcIn->mName + ".Target";
-
- aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(nd->mName);
-
- nda->mNumPositionKeys = (unsigned int)distanceTrack.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys,&distanceTrack[0],
- sizeof(aiVectorKey)*nda->mNumPositionKeys);
- }
-#endif
-
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
- for (unsigned int n = 0; n < pcSOut->mNumCameras;++n) {
- if (pcSOut->mCameras[n]->mName == pcOut->mName) {
- pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
- }
- }
- for (unsigned int n = 0; n < pcSOut->mNumLights;++n) {
- if (pcSOut->mLights[n]->mName == pcOut->mName) {
- pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
- }
- }
-
- // Allocate a new node anim and setup its name
- aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(pcIn->mName);
-
- // POSITION keys
- if (pcIn->aPositionKeys.size() > 0)
- {
- nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys,&pcIn->aPositionKeys[0],
- sizeof(aiVectorKey)*nda->mNumPositionKeys);
- }
-
- // ROTATION keys
- if (pcIn->aRotationKeys.size() > 0)
- {
- nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
- nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
-
- // Rotations are quaternion offsets
- aiQuaternion abs;
- for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
- {
- const aiQuatKey& q = pcIn->aRotationKeys[n];
-
- abs = (n ? abs * q.mValue : q.mValue);
- nda->mRotationKeys[n].mTime = q.mTime;
- nda->mRotationKeys[n].mValue = abs.Normalize();
- }
- }
-
- // SCALING keys
- if (pcIn->aScalingKeys.size() > 0)
- {
- nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
- nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
- ::memcpy(nda->mScalingKeys,&pcIn->aScalingKeys[0],
- sizeof(aiVectorKey)*nda->mNumScalingKeys);
- }
- }
-
- // Allocate storage for children
- pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
- pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
-
- // Recursively process all children
- const unsigned int size = pcIn->mChildren.size();
- for (unsigned int i = 0; i < size;++i)
- {
- pcOut->mChildren[i] = new aiNode();
- pcOut->mChildren[i]->mParent = pcOut;
- AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find out how many node animation channels we'll have finally
-void CountTracks(D3DS::Node* node, unsigned int& cnt)
-{
- //////////////////////////////////////////////////////////////////////////////
- // We will never generate more than one channel for a node, so
- // this is rather easy here.
-
- if (node->aPositionKeys.size() > 1 || node->aRotationKeys.size() > 1 ||
- node->aScalingKeys.size() > 1 || node->aCameraRollKeys.size() > 1 ||
- node->aTargetPositionKeys.size() > 1)
- {
- ++cnt;
-
- // account for the additional channel for the camera/spotlight target position
- if (node->aTargetPositionKeys.size() > 1)++cnt;
- }
-
- // Recursively process all children
- for (unsigned int i = 0; i < node->mChildren.size();++i)
- CountTracks(node->mChildren[i],cnt);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate the output node graph
-void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
-{
- pcOut->mRootNode = new aiNode();
- if (0 == mRootNode->mChildren.size())
- {
- //////////////////////////////////////////////////////////////////////////////
- // It seems the file is so fucked up that it has not even a hierarchy.
- // generate a flat hiearachy which looks like this:
- //
- // ROOT_NODE
- // |
- // ----------------------------------------
- // | | | | |
- // MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 ....
- //
- DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
-
- pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
- mScene->mCameras.size() + mScene->mLights.size();
-
- pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
- pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
-
- // Build dummy nodes for all meshes
- unsigned int a = 0;
- for (unsigned int i = 0; i < pcOut->mNumMeshes;++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- pcNode->mNumMeshes = 1;
-
- // Build a name for the node
- pcNode->mName.length = sprintf(pcNode->mName.data,"3DSMesh_%i",i);
- //fprintf(stderr, "XXXX created dummy node: %s\n", pcNode->mName.data);
- }
-
- // Build dummy nodes for all cameras
- for (unsigned int i = 0; i < (unsigned int )mScene->mCameras.size();++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mCameras[i]->mName;
- }
-
- // Build dummy nodes for all lights
- for (unsigned int i = 0; i < (unsigned int )mScene->mLights.size();++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mLights[i]->mName;
- }
- }
- else
- {
- // First of all: find out how many scaling, rotation and translation
- // animation tracks we'll have afterwards
- unsigned int numChannel = 0;
- CountTracks(mRootNode,numChannel);
-
- if (numChannel)
- {
- // Allocate a primary animation channel
- pcOut->mNumAnimations = 1;
- pcOut->mAnimations = new aiAnimation*[1];
- aiAnimation* anim = pcOut->mAnimations[0] = new aiAnimation();
-
- anim->mName.Set("3DSMasterAnim");
-
- // Allocate enough storage for all node animation channels,
- // but don't set the mNumChannels member - we'll use it to
- // index into the array
- anim->mChannels = new aiNodeAnim*[numChannel];
- }
-
- aiMatrix4x4 m;
- AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
- }
-
- // We used the first vertex color set to store some emporary values so we need to cleanup here
- for (unsigned int a = 0; a < pcOut->mNumMeshes;++a)
- pcOut->mMeshes[a]->mColors[0] = NULL;
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pcOut->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f) * pcOut->mRootNode->mTransformation;
-
- // If the root node is unnamed name it "<3DSRoot>"
- if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) ||
- (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$') )
- {
- pcOut->mRootNode->mName.Set("<3DSRoot>");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert all meshes in the scene and generate the final output scene.
-void Discreet3DSImporter::ConvertScene(aiScene* pcOut)
-{
- // Allocate enough storage for all output materials
- pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
- pcOut->mMaterials = new aiMaterial*[pcOut->mNumMaterials];
-
- // ... and convert the 3DS materials to aiMaterial's
- for (unsigned int i = 0; i < pcOut->mNumMaterials;++i)
- {
- MaterialHelper* pcNew = new MaterialHelper();
- ConvertMaterial(mScene->mMaterials[i],*pcNew);
- pcOut->mMaterials[i] = pcNew;
- }
-
- // Generate the output mesh list
- ConvertMeshes(pcOut);
-
- // Now copy all light sources to the output scene
- pcOut->mNumLights = (unsigned int)mScene->mLights.size();
- if (pcOut->mNumLights)
- {
- pcOut->mLights = new aiLight*[pcOut->mNumLights];
- ::memcpy(pcOut->mLights,&mScene->mLights[0],sizeof(void*)*pcOut->mNumLights);
- }
-
- // Now copy all cameras to the output scene
- pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
- if (pcOut->mNumCameras)
- {
- pcOut->mCameras = new aiCamera*[pcOut->mNumCameras];
- ::memcpy(pcOut->mCameras,&mScene->mCameras[0],sizeof(void*)*pcOut->mNumCameras);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/3rdparty/assimp/code/3DSHelper.h b/3rdparty/assimp/code/3DSHelper.h
deleted file mode 100644
index db37415f..00000000
--- a/3rdparty/assimp/code/3DSHelper.h
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines helper data structures for the import of 3DS files */
-
-#ifndef AI_3DSFILEHELPER_H_INC
-#define AI_3DSFILEHELPER_H_INC
-
-
-#include "SpatialSort.h"
-#include "SmoothingGroups.h"
-
-namespace Assimp {
-namespace D3DS {
-
-#include "./../include/Compiler/pushpack1.h"
-
-// ---------------------------------------------------------------------------
-/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
-* and data structures.
-*/
-class Discreet3DS
-{
-private:
- inline Discreet3DS() {}
-
-public:
-
- //! data structure for a single chunk in a .3ds file
- struct Chunk
- {
- uint16_t Flag;
- uint32_t Size;
- } PACK_STRUCT;
-
-
- //! Used for shading field in material3ds structure
- //! From AutoDesk 3ds SDK
- typedef enum
- {
- // translated to gouraud shading with wireframe active
- Wire = 0x0,
-
- // if this material is set, no vertex normals will
- // be calculated for the model. Face normals + gouraud
- Flat = 0x1,
-
- // standard gouraud shading
- Gouraud = 0x2,
-
- // phong shading
- Phong = 0x3,
-
- // cooktorrance or anistropic phong shading ...
- // the exact meaning is unknown, if you know it
- // feel free to tell me ;-)
- Metal = 0x4,
-
- // required by the ASE loader
- Blinn = 0x5
- } shadetype3ds;
-
- // Flags for animated keys
- enum
- {
- KEY_USE_TENS = 0x1,
- KEY_USE_CONT = 0x2,
- KEY_USE_BIAS = 0x4,
- KEY_USE_EASE_TO = 0x8,
- KEY_USE_EASE_FROM = 0x10
- } ;
-
- enum
- {
-
- // ********************************************************************
- // Basic chunks which can be found everywhere in the file
- CHUNK_VERSION = 0x0002,
- CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
- CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
-
- // Linear color values (gamma = 2.2?)
- CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
- CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
-
- CHUNK_PERCENTW = 0x0030, // int2 percentage
- CHUNK_PERCENTF = 0x0031, // float4 percentage
- // ********************************************************************
-
- // Prj master chunk
- CHUNK_PRJ = 0xC23D,
-
- // MDLI master chunk
- CHUNK_MLI = 0x3DAA,
-
- // Primary main chunk of the .3ds file
- CHUNK_MAIN = 0x4D4D,
-
- // Mesh main chunk
- CHUNK_OBJMESH = 0x3D3D,
-
- // Specifies the background color of the .3ds file
- // This is passed through the material system for
- // viewing purposes.
- CHUNK_BKGCOLOR = 0x1200,
-
- // Specifies the ambient base color of the scene.
- // This is added to all materials in the file
- CHUNK_AMBCOLOR = 0x2100,
-
- // Specifies the background image for the whole scene
- // This value is passed through the material system
- // to the viewer
- CHUNK_BIT_MAP = 0x1100,
- CHUNK_BIT_MAP_EXISTS = 0x1101,
-
- // ********************************************************************
- // Viewport related stuff. Ignored
- CHUNK_DEFAULT_VIEW = 0x3000,
- CHUNK_VIEW_TOP = 0x3010,
- CHUNK_VIEW_BOTTOM = 0x3020,
- CHUNK_VIEW_LEFT = 0x3030,
- CHUNK_VIEW_RIGHT = 0x3040,
- CHUNK_VIEW_FRONT = 0x3050,
- CHUNK_VIEW_BACK = 0x3060,
- CHUNK_VIEW_USER = 0x3070,
- CHUNK_VIEW_CAMERA = 0x3080,
- // ********************************************************************
-
- // Mesh chunks
- CHUNK_OBJBLOCK = 0x4000,
- CHUNK_TRIMESH = 0x4100,
- CHUNK_VERTLIST = 0x4110,
- CHUNK_VERTFLAGS = 0x4111,
- CHUNK_FACELIST = 0x4120,
- CHUNK_FACEMAT = 0x4130,
- CHUNK_MAPLIST = 0x4140,
- CHUNK_SMOOLIST = 0x4150,
- CHUNK_TRMATRIX = 0x4160,
- CHUNK_MESHCOLOR = 0x4165,
- CHUNK_TXTINFO = 0x4170,
- CHUNK_LIGHT = 0x4600,
- CHUNK_CAMERA = 0x4700,
- CHUNK_HIERARCHY = 0x4F00,
-
- // Specifies the global scaling factor. This is applied
- // to the root node's transformation matrix
- CHUNK_MASTER_SCALE = 0x0100,
-
- // ********************************************************************
- // Material chunks
- CHUNK_MAT_MATERIAL = 0xAFFF,
-
- // asciiz containing the name of the material
- CHUNK_MAT_MATNAME = 0xA000,
- CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
- CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
- CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
-
- // Specifies the shininess of the material
- // followed by percentage chunk
- CHUNK_MAT_SHININESS = 0xA040,
- CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
-
- // Specifies the shading mode to be used
- // followed by a short
- CHUNK_MAT_SHADING = 0xA100,
-
- // NOTE: Emissive color (self illumination) seems not
- // to be a color but a single value, type is unknown.
- // Make the parser accept both of them.
- // followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILLUM = 0xA080,
-
- // Always followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILPCT = 0xA084,
-
- // Always followed by percentage chunk
- CHUNK_MAT_TRANSPARENCY = 0xA050,
-
- // Diffuse texture channel 0
- CHUNK_MAT_TEXTURE = 0xA200,
-
- // Contains opacity information for each texel
- CHUNK_MAT_OPACMAP = 0xA210,
-
- // Contains a reflection map to be used to reflect
- // the environment. This is partially supported.
- CHUNK_MAT_REFLMAP = 0xA220,
-
- // Self Illumination map (emissive colors)
- CHUNK_MAT_SELFIMAP = 0xA33d,
-
- // Bumpmap. Not specified whether it is a heightmap
- // or a normal map. Assme it is a heightmap since
- // artist normally prefer this format.
- CHUNK_MAT_BUMPMAP = 0xA230,
-
- // Specular map. Seems to influence the specular color
- CHUNK_MAT_SPECMAP = 0xA204,
-
- // Holds shininess data.
- CHUNK_MAT_MAT_SHINMAP = 0xA33C,
-
- // Scaling in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_USCALE = 0xA354,
- CHUNK_MAT_MAP_VSCALE = 0xA356,
-
- // Translation in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_UOFFSET = 0xA358,
- CHUNK_MAT_MAP_VOFFSET = 0xA35a,
-
- // UV-coordinates rotation around the z-axis
- // Assumed to be in radians.
- CHUNK_MAT_MAP_ANG = 0xA35C,
-
- // Tiling flags for 3DS files
- CHUNK_MAT_MAP_TILING = 0xa351,
-
- // Specifies the file name of a texture
- CHUNK_MAPFILE = 0xA300,
-
- // Specifies whether a materail requires two-sided rendering
- CHUNK_MAT_TWO_SIDE = 0xA081,
- // ********************************************************************
-
- // Main keyframer chunk. Contains translation/rotation/scaling data
- CHUNK_KEYFRAMER = 0xB000,
-
- // Supported sub chunks
- CHUNK_TRACKINFO = 0xB002,
- CHUNK_TRACKOBJNAME = 0xB010,
- CHUNK_TRACKDUMMYOBJNAME = 0xB011,
- CHUNK_TRACKPIVOT = 0xB013,
- CHUNK_TRACKPOS = 0xB020,
- CHUNK_TRACKROTATE = 0xB021,
- CHUNK_TRACKSCALE = 0xB022,
-
- // ********************************************************************
- // Keyframes for various other stuff in the file
- // Partially ignored
- CHUNK_AMBIENTKEY = 0xB001,
- CHUNK_TRACKMORPH = 0xB026,
- CHUNK_TRACKHIDE = 0xB029,
- CHUNK_OBJNUMBER = 0xB030,
- CHUNK_TRACKCAMERA = 0xB003,
- CHUNK_TRACKFOV = 0xB023,
- CHUNK_TRACKROLL = 0xB024,
- CHUNK_TRACKCAMTGT = 0xB004,
- CHUNK_TRACKLIGHT = 0xB005,
- CHUNK_TRACKLIGTGT = 0xB006,
- CHUNK_TRACKSPOTL = 0xB007,
- CHUNK_FRAMES = 0xB008,
- // ********************************************************************
-
- // light sub-chunks
- CHUNK_DL_OFF = 0x4620,
- CHUNK_DL_OUTER_RANGE = 0x465A,
- CHUNK_DL_INNER_RANGE = 0x4659,
- CHUNK_DL_MULTIPLIER = 0x465B,
- CHUNK_DL_EXCLUDE = 0x4654,
- CHUNK_DL_ATTENUATE = 0x4625,
- CHUNK_DL_SPOTLIGHT = 0x4610,
-
- // camera sub-chunks
- CHUNK_CAM_RANGES = 0x4720
- };
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds mesh face */
-struct Face : public FaceWithSmoothingGroup
-{
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a texture */
-struct Texture
-{
- //! Default constructor
- Texture()
- : mOffsetU (0.0f)
- , mOffsetV (0.0f)
- , mScaleU (1.0f)
- , mScaleV (1.0f)
- , mRotation (0.0f)
- , mMapMode (aiTextureMapMode_Wrap)
- , iUVSrc (0)
- {
- mTextureBlend = get_qnan();
- }
-
- //! Specifies the blend factor for the texture
- float mTextureBlend;
-
- //! Specifies the filename of the texture
- std::string mMapName;
-
- //! Specifies texture coordinate offsets/scaling/rotations
- float mOffsetU;
- float mOffsetV;
- float mScaleU;
- float mScaleV;
- float mRotation;
-
- //! Specifies the mapping mode to be used for the texture
- aiTextureMapMode mMapMode;
-
- //! Used internally
- bool bPrivate;
- int iUVSrc;
-};
-
-#include "./../include/Compiler/poppack1.h"
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds material */
-struct Material
-{
- //! Default constructor. Builds a default name for the material
- Material()
- :
- mDiffuse (0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
- mSpecularExponent (0.0f),
- mShininessStrength (1.0f),
- mShading(Discreet3DS::Gouraud),
- mTransparency (1.0f),
- mBumpHeight (1.0f),
- mTwoSided (false)
- {
- static int iCnt = 0;
-
- char szTemp[128];
- sprintf(szTemp,"UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Name of the material
- std::string mName;
- //! Diffuse color of the material
- aiColor3D mDiffuse;
- //! Specular exponent
- float mSpecularExponent;
- //! Shininess strength, in percent
- float mShininessStrength;
- //! Specular color of the material
- aiColor3D mSpecular;
- //! Ambient color of the material
- aiColor3D mAmbient;
- //! Shading type to be used
- Discreet3DS::shadetype3ds mShading;
- //! Opacity of the material
- float mTransparency;
- //! Diffuse texture channel
- Texture sTexDiffuse;
- //! Opacity texture channel
- Texture sTexOpacity;
- //! Specular texture channel
- Texture sTexSpecular;
- //! Reflective texture channel
- Texture sTexReflective;
- //! Bump texture channel
- Texture sTexBump;
- //! Emissive texture channel
- Texture sTexEmissive;
- //! Shininess texture channel
- Texture sTexShininess;
- //! Scaling factor for the bump values
- float mBumpHeight;
- //! Emissive color
- aiColor3D mEmissive;
- //! Ambient texture channel
- //! (used by the ASE format)
- Texture sTexAmbient;
- //! True if the material must be rendered from two sides
- bool mTwoSided;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file mesh */
-struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
-{
- //! Default constructor
- Mesh()
- {
- static int iCnt = 0;
-
- // Generate a default name for the mesh
- char szTemp[128];
- ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Name of the mesh
- std::string mName;
-
- //! Texture coordinates
- std::vector<aiVector3D> mTexCoords;
-
- //! Face materials
- std::vector<unsigned int> mFaceMaterials;
-
- //! Local transformation matrix
- aiMatrix4x4 mMat;
-};
-
-// ---------------------------------------------------------------------------
-/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
- C-API, so it would be difficult to make them a template. */
-struct aiFloatKey
-{
- double mTime; ///< The time of this key
- float mValue; ///< The value of this key
-
-#ifdef __cplusplus
-
- // time is not compared
- bool operator == (const aiFloatKey& o) const
- {return o.mValue == this->mValue;}
-
- bool operator != (const aiFloatKey& o) const
- {return o.mValue != this->mValue;}
-
- // Only time is compared. This operator is defined
- // for use with std::sort
- bool operator < (const aiFloatKey& o) const
- {return mTime < o.mTime;}
-
- bool operator > (const aiFloatKey& o) const
- {return mTime < o.mTime;}
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file node */
-struct Node
-{
- Node()
-
- : mHierarchyPos (0)
- , mHierarchyIndex (0)
-
- {
- static int iCnt = 0;
-
- // Generate a default name for the node
- char szTemp[128];
- ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
- mName = szTemp;
-
- aRotationKeys.reserve (20);
- aPositionKeys.reserve (20);
- aScalingKeys.reserve (20);
- }
-
- ~Node()
- {
- for (unsigned int i = 0; i < mChildren.size();++i)
- delete mChildren[i];
- }
-
- //! Pointer to the parent node
- Node* mParent;
-
- //! Holds all child nodes
- std::vector<Node*> mChildren;
-
- //! Name of the node
- std::string mName;
-
- //! Dummy nodes: real name to be combined with the $$$DUMMY
- std::string mDummyName;
-
- //! Position of the node in the hierarchy (tree depth)
- int16_t mHierarchyPos;
-
- //! Index of the node
- int16_t mHierarchyIndex;
-
- //! Rotation keys loaded from the file
- std::vector<aiQuatKey> aRotationKeys;
-
- //! Position keys loaded from the file
- std::vector<aiVectorKey> aPositionKeys;
-
- //! Scaling keys loaded from the file
- std::vector<aiVectorKey> aScalingKeys;
-
-
- // For target lights (spot lights and directional lights):
- // The position of the target
- std::vector< aiVectorKey > aTargetPositionKeys;
-
- // For cameras: the camera roll angle
- std::vector< aiFloatKey > aCameraRollKeys;
-
- //! Pivot position loaded from the file
- aiVector3D vPivot;
-
- //! Add a child node, setup the right parent node for it
- //! \param pc Node to be 'adopted'
- inline Node& push_back(Node* pc)
- {
- mChildren.push_back(pc);
- pc->mParent = this;
- return *this;
- }
-};
-// ---------------------------------------------------------------------------
-/** Helper structure analogue to aiScene */
-struct Scene
-{
- //! List of all materials loaded
- //! NOTE: 3ds references materials globally
- std::vector<Material> mMaterials;
-
- //! List of all meshes loaded
- std::vector<Mesh> mMeshes;
-
- //! List of all cameras loaded
- std::vector<aiCamera*> mCameras;
-
- //! List of all lights loaded
- std::vector<aiLight*> mLights;
-
- //! Pointer to the root node of the scene
- // --- moved to main class
- // Node* pcRootNode;
-};
-
-
-} // end of namespace D3DS
-} // end of namespace Assimp
-
-#endif // AI_XFILEHELPER_H_INC
diff --git a/3rdparty/assimp/code/3DSLoader.cpp b/3rdparty/assimp/code/3DSLoader.cpp
deleted file mode 100644
index 4a382f9a..00000000
--- a/3rdparty/assimp/code/3DSLoader.cpp
+++ /dev/null
@@ -1,1376 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file 3DSLoader.cpp
- * @brief Implementation of the 3ds importer class
- *
- * http://www.the-labs.com/Blender/3DS-details.html
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "3DSLoader.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Begins a new parsing block
-// - Reads the current chunk and validates it
-// - computes its length
-#define ASSIMP_3DS_BEGIN_CHUNK() \
- while (true) { \
- if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)){ \
- return; \
- } \
- Discreet3DS::Chunk chunk; \
- ReadChunk(&chunk); \
- int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
- const int oldReadLimit = stream->GetReadLimit(); \
- stream->SetReadLimit(stream->GetCurrentPos() + chunkSize); \
-
-
-// ------------------------------------------------------------------------------------------------
-// End a parsing block
-// Must follow at the end of each parsing block, reset chunk end marker to previous value
-#define ASSIMP_3DS_END_CHUNK() \
- stream->SkipToReadLimit(); \
- stream->SetReadLimit(oldReadLimit); \
- if (stream->GetRemainingSizeToLimit() == 0) \
- return; \
- }
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-Discreet3DSImporter::Discreet3DSImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
- if (extension == "3ds" || extension == "prj" ) {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint16_t token[3];
- token[0] = 0x4d4d;
- token[1] = 0x3dc2;
- //token[2] = 0x3daa;
- return CheckMagicToken(pIOHandler,pFile,token,2,0,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of all extension supported by this loader
-void Discreet3DSImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("3ds");
- extensions.insert("prj");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void Discreet3DSImporter::SetupProperties(const Importer* /* pImp */)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void Discreet3DSImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
- this->stream = &stream;
-
- // We should have at least one chunk
- if (stream.GetRemainingSize() < 16) {
- throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
- }
-
- // Allocate our temporary 3DS representation
- mScene = new D3DS::Scene();
-
- // Initialize members
- mLastNodeIndex = -1;
- mCurrentNode = new D3DS::Node();
- mRootNode = mCurrentNode;
- mRootNode->mHierarchyPos = -1;
- mRootNode->mHierarchyIndex = -1;
- mRootNode->mParent = NULL;
- mMasterScale = 1.0f;
- mBackgroundImage = "";
- bHasBG = false;
- bIsPrj = false;
-
- // Parse the file
- ParseMainChunk();
-
- // Process all meshes in the file. First check whether all
- // face indices haev valid values. The generate our
- // internal verbose representation. Finally compute normal
- // vectors from the smoothing groups we read from the
- // file.
- for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(),
- end = mScene->mMeshes.end(); i != end;++i) {
- CheckIndices(*i);
- MakeUnique (*i);
- ComputeNormalsWithSmoothingsGroups<D3DS::Face>(*i);
- }
-
- // Replace all occurences of the default material with a
- // valid material. Generate it if no material containing
- // DEFAULT in its name has been found in the file
- ReplaceDefaultMaterial();
-
- // Convert the scene from our internal representation to an
- // aiScene object. This involves copying all meshes, lights
- // and cameras to the scene
- ConvertScene(pScene);
-
- // Generate the node graph for the scene. This is a little bit
- // tricky since we'll need to split some meshes into submeshes
- GenerateNodeGraph(pScene);
-
- // Now apply the master scaling factor to the scene
- ApplyMasterScale(pScene);
-
- // Delete our internal scene representation and the root
- // node, so the whole hierarchy will follow
- delete mRootNode;
- delete mScene;
-
- AI_DEBUG_INVALIDATE_PTR(mRootNode);
- AI_DEBUG_INVALIDATE_PTR(mScene);
- AI_DEBUG_INVALIDATE_PTR(this->stream);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Applies a master-scaling factor to the imported scene
-void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
-{
- // There are some 3DS files with a zero scaling factor
- if (!mMasterScale)mMasterScale = 1.0f;
- else mMasterScale = 1.0f / mMasterScale;
-
- // Construct an uniform scaling matrix and multiply with it
- pScene->mRootNode->mTransformation *= aiMatrix4x4(
- mMasterScale,0.0f, 0.0f, 0.0f,
- 0.0f, mMasterScale,0.0f, 0.0f,
- 0.0f, 0.0f, mMasterScale,0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- // Check whether a scaling track is assigned to the root node.
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a new chunk from the file
-void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
-{
- ai_assert(pcOut != NULL);
-
- pcOut->Flag = stream->GetI2();
- pcOut->Size = stream->GetI4();
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize())
- throw DeadlyImportError("Chunk is too large");
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit())
- DefaultLogger::get()->error("3DS: Chunk overflow");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip a chunk
-void Discreet3DSImporter::SkipChunk()
-{
- Discreet3DS::Chunk psChunk;
- ReadChunk(&psChunk);
-
- stream->IncPtr(psChunk.Size-sizeof(Discreet3DS::Chunk));
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Process the primary chunk of the file
-void Discreet3DSImporter::ParseMainChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
-
- case Discreet3DS::CHUNK_PRJ:
- bIsPrj = true;
- case Discreet3DS::CHUNK_MAIN:
- ParseEditorChunk();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
- // recursively continue processing this hierarchy level
- return ParseMainChunk();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseEditorChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_OBJMESH:
-
- ParseObjectChunk();
- break;
-
- // NOTE: In several documentations in the internet this
- // chunk appears at different locations
- case Discreet3DS::CHUNK_KEYFRAMER:
-
- ParseKeyframeChunk();
- break;
-
- case Discreet3DS::CHUNK_VERSION:
- {
- // print the version number
- char buff[10];
- ASSIMP_itoa10(buff,stream->GetI2());
- DefaultLogger::get()->info(std::string("3DS file format version: ") + buff);
- }
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseObjectChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_OBJBLOCK:
- {
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
-
- // Get the name of the geometry object
- while (stream->GetI1())++cnt;
- ParseChunk(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_MATERIAL:
-
- // Add a new material to the list
- mScene->mMaterials.push_back(D3DS::Material());
- ParseMaterialChunk();
- break;
-
- case Discreet3DS::CHUNK_AMBCOLOR:
-
- // This is the ambient base color of the scene.
- // We add it to the ambient color of all materials
- ParseColorChunk(&mClrAmbient,true);
- if (is_qnan(mClrAmbient.r))
- {
- // We failed to read the ambient base color.
- DefaultLogger::get()->error("3DS: Failed to read ambient base color");
- mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_BIT_MAP:
- {
- // Specifies the background image. The string should already be
- // properly 0 terminated but we need to be sure
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
- while (stream->GetI1())++cnt;
- mBackgroundImage = std::string(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
- bHasBG = true;
- break;
-
- case Discreet3DS::CHUNK_MASTER_SCALE:
- // Scene master scaling factor
- mMasterScale = stream->GetF4();
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-#include <QtCore/qstring.h>
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // IMPLEMENTATION NOTE;
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRIMESH:
- {
- // this starts a new triangle mesh
- mScene->mMeshes.push_back(D3DS::Mesh());
- D3DS::Mesh& m = mScene->mMeshes.back();
-
- // Setup the name of the mesh
- m.mName = std::string(name, num);
-
- // Read mesh chunks
- ParseMeshChunk();
- }
- break;
-
- case Discreet3DS::CHUNK_LIGHT:
- {
- // This starts a new light
- aiLight* light = new aiLight();
- mScene->mLights.push_back(light);
-
- light->mName.Set(std::string(name, num));
-
- // First read the position of the light
- light->mPosition.x = stream->GetF4();
- light->mPosition.y = stream->GetF4();
- light->mPosition.z = stream->GetF4();
-
- light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */
- ParseLightChunk();
-
- // The specular light color is identical the the diffuse light color. The ambient light color
- // is equal to the ambient base color of the whole scene.
- light->mColorSpecular = light->mColorDiffuse;
- light->mColorAmbient = mClrAmbient;
-
- if (light->mType == aiLightSource_UNDEFINED)
- {
- // It must be a point light
- light->mType = aiLightSource_POINT;
- }}
- break;
-
- case Discreet3DS::CHUNK_CAMERA:
- {
- // This starts a new camera
- aiCamera* camera = new aiCamera();
- mScene->mCameras.push_back(camera);
- camera->mName.Set(std::string(name, num));
-
- // First read the position of the camera
- camera->mPosition.x = stream->GetF4();
- camera->mPosition.y = stream->GetF4();
- camera->mPosition.z = stream->GetF4();
-
- // Then the camera target
- camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
- camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
- camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
- float len = camera->mLookAt.Length();
- if (len < 1e-5f) {
-
- // There are some files with lookat == position. Don't know why or whether it's ok or not.
- DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
- camera->mLookAt = aiVector3D(0.f,1.f,0.f);
-
- }
- else camera->mLookAt /= len;
-
- // And finally - the camera rotation angle, in counter clockwise direction
- const float angle = AI_DEG_TO_RAD( stream->GetF4() );
- aiQuaternion quat(camera->mLookAt,angle);
- camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
-
- // Read the lense angle
- camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
- if (camera->mHorizontalFOV < 0.001f) {
- camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
- }
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */ {
- ParseCameraChunk();
- }}
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseLightChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- aiLight* light = mScene->mLights.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_DL_SPOTLIGHT:
- // Now we can be sure that the light is a spot light
- light->mType = aiLightSource_SPOT;
-
- // We wouldn't need to normalize here, but we do it
- light->mDirection.x = stream->GetF4() - light->mPosition.x;
- light->mDirection.y = stream->GetF4() - light->mPosition.y;
- light->mDirection.z = stream->GetF4() - light->mPosition.z;
- light->mDirection.Normalize();
-
- // Now the hotspot and falloff angles - in degrees
- light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
-
- // FIX: the falloff angle is just an offset
- light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() );
- break;
-
- // intensity multiplier
- case Discreet3DS::CHUNK_DL_MULTIPLIER:
- light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
- break;
-
- // light color
- case Discreet3DS::CHUNK_RGBF:
- case Discreet3DS::CHUNK_LINRGBF:
- light->mColorDiffuse.r *= stream->GetF4();
- light->mColorDiffuse.g *= stream->GetF4();
- light->mColorDiffuse.b *= stream->GetF4();
- break;
-
- // light attenuation
- case Discreet3DS::CHUNK_DL_ATTENUATE:
- light->mAttenuationLinear = stream->GetF4();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseCameraChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- aiCamera* camera = mScene->mCameras.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- // near and far clip plane
- case Discreet3DS::CHUNK_CAM_RANGES:
- camera->mClipPlaneNear = stream->GetF4();
- camera->mClipPlaneFar = stream->GetF4();
- break;
- }
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseKeyframeChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRACKCAMTGT:
- case Discreet3DS::CHUNK_TRACKSPOTL:
- case Discreet3DS::CHUNK_TRACKCAMERA:
- case Discreet3DS::CHUNK_TRACKINFO:
- case Discreet3DS::CHUNK_TRACKLIGHT:
- case Discreet3DS::CHUNK_TRACKLIGTGT:
-
- // this starts a new mesh hierarchy chunk
- ParseHierarchyChunk(chunk.Flag);
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Little helper function for ParseHierarchyChunk
-void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent)
-{
- if (!pcCurrent) {
- mRootNode->push_back(pcNode);
- return;
- }
-
- if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) {
- if (pcCurrent->mParent) {
- pcCurrent->mParent->push_back(pcNode);
- }
- else pcCurrent->push_back(pcNode);
- return;
- }
- return InverseNodeSearch(pcNode,pcCurrent->mParent);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a node with a specific name in the import hierarchy
-D3DS::Node* FindNode(D3DS::Node* root, const std::string& name)
-{
- if (root->mName == name)
- return root;
- for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) {
- D3DS::Node* nd;
- if (( nd = FindNode(*it,name)))
- return nd;
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Binary predicate for std::unique()
-template <class T>
-bool KeyUniqueCompare(const T& first, const T& second)
-{
- return first.mTime == second.mTime;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip some additional import data.
-void Discreet3DSImporter::SkipTCBInfo()
-{
- unsigned int flags = stream->GetI2();
-
- if (!flags) {
- // Currently we can't do anything with these values. They occur
- // quite rare, so it wouldn't be worth the effort implementing
- // them. 3DS ist not really suitable for complex animations,
- // so full support is not required.
- DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
- }
-
- if (flags & Discreet3DS::KEY_USE_TENS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_BIAS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_CONT) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_TO) {
- stream->IncPtr(4);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read hierarchy and keyframe info
-void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRACKOBJNAME:
-
- // This is the name of the object to which the track applies. The chunk also
- // defines the position of this object in the hierarchy.
- {
-
- // First of all: get the name of the object
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
-
- while (stream->GetI1())++cnt;
- std::string name = std::string(sz,cnt);
-
- // Now find out whether we have this node already (target animation channels
- // are stored with a separate object ID)
- D3DS::Node* pcNode = FindNode(mRootNode,name);
- if (pcNode)
- {
- // Make this node the current node
- mCurrentNode = pcNode;
- break;
- }
- pcNode = new D3DS::Node();
- pcNode->mName = name;
-
- // There are two unknown values which we can safely ignore
- stream->IncPtr(4);
-
- // Now read the hierarchy position of the object
- uint16_t hierarchy = stream->GetI2() + 1;
- pcNode->mHierarchyPos = hierarchy;
- pcNode->mHierarchyIndex = mLastNodeIndex;
-
- // And find a proper position in the graph for it
- if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) {
-
- // add to the parent of the last touched node
- mCurrentNode->mParent->push_back(pcNode);
- mLastNodeIndex++;
- }
- else if (hierarchy >= mLastNodeIndex) {
-
- // place it at the current position in the hierarchy
- mCurrentNode->push_back(pcNode);
- mLastNodeIndex = hierarchy;
- }
- else {
- // need to go back to the specified position in the hierarchy.
- InverseNodeSearch(pcNode,mCurrentNode);
- mLastNodeIndex++;
- }
- // Make this node the current node
- mCurrentNode = pcNode;
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKDUMMYOBJNAME:
-
- // This is the "real" name of a $$$DUMMY object
- {
- const char* sz = (const char*) stream->GetPtr();
- while (stream->GetI1()) {};
-
- // If object name is DUMMY, take this one instead
- if (mCurrentNode->mName == "$$$DUMMY") {
- //DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
- mCurrentNode->mName = std::string(sz);
- break;
- }
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKPIVOT:
-
- if ( Discreet3DS::CHUNK_TRACKINFO != parent)
- {
- DefaultLogger::get()->warn("3DS: Skipping pivot subchunk for non usual object");
- break;
- }
-
- // Pivot = origin of rotation and scaling
- mCurrentNode->vPivot.x = stream->GetF4();
- mCurrentNode->vPivot.y = stream->GetF4();
- mCurrentNode->vPivot.z = stream->GetF4();
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // POSITION KEYFRAME
- case Discreet3DS::CHUNK_TRACKPOS:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- bool sortKeys = false;
-
- // This could also be meant as the target position for
- // (targeted) lights and cameras
- std::vector<aiVectorKey>* l;
- if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent) {
- l = & mCurrentNode->aTargetPositionKeys;
- }
- else l = & mCurrentNode->aPositionKeys;
-
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- SkipTCBInfo();
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
- }}
-
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA ROLL KEYFRAME
- case Discreet3DS::CHUNK_TRACKROLL:
- {
- // roll keys are accepted for cameras only
- if (parent != Discreet3DS::CHUNK_TRACKCAMERA) {
- DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object");
- break;
- }
- bool sortKeys = false;
- std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys;
-
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiFloatKey v;
- v.mTime = (double)fidx;
-
- // This is just a single float
- SkipTCBInfo();
- v.mValue = stream->GetF4();
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
- }}
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA FOV KEYFRAME
- case Discreet3DS::CHUNK_TRACKFOV:
- {
- DefaultLogger::get()->error("3DS: Skipping FOV animation track. "
- "This is not supported");
- }
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // ROTATION KEYFRAME
- case Discreet3DS::CHUNK_TRACKROTATE:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
-
- bool sortKeys = false;
- std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- aiQuatKey v;
- v.mTime = (double)fidx;
-
- // The rotation keyframe is given as an axis-angle pair
- const float rad = stream->GetF4();
- aiVector3D axis;
- axis.x = stream->GetF4();
- axis.y = stream->GetF4();
- axis.z = stream->GetF4();
-
- if (!axis.x && !axis.y && !axis.z)
- axis.y = 1.f;
-
- // Construct a rotation quaternion from the axis-angle pair
- v.mValue = aiQuaternion(axis,rad);
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // add the new keyframe to the list
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
- }}
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // SCALING KEYFRAME
- case Discreet3DS::CHUNK_TRACKSCALE:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI2();
- stream->IncPtr(2);
-
- bool sortKeys = false;
- std::vector<aiVectorKey>* l = &mCurrentNode->aScalingKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- // Setup a new key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- // ... and read its value
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Remove zero-scalings on singular axes - they've been reported to be there erroneously in some strange files
- if (!v.mValue.x) v.mValue.x = 1.f;
- if (!v.mValue.y) v.mValue.y = 1.f;
- if (!v.mValue.z) v.mValue.z = 1.f;
-
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
- }}
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a face chunk - it contains smoothing groups and material assignments
-void Discreet3DSImporter::ParseFaceChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh& mMesh = mScene->mMeshes.back();
-
- // Get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_SMOOLIST:
- {
- // This is the list of smoothing groups - a bitfield for every face.
- // Up to 32 smoothing groups assigned to a single face.
- unsigned int num = chunkSize/4, m = 0;
- for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) {
- // nth bit is set for nth smoothing group
- (*i).iSmoothGroup = stream->GetI4();
- }}
- break;
-
- case Discreet3DS::CHUNK_FACEMAT:
- {
- // at fist an asciiz with the material name
- const char* sz = (const char*)stream->GetPtr();
- while (stream->GetI1()) {};
-
- // find the index of the material
- unsigned int idx = 0xcdcdcdcd, cnt = 0;
- for (std::vector<D3DS::Material>::const_iterator i = mScene->mMaterials.begin();i != mScene->mMaterials.end();++i,++cnt) {
- // use case independent comparisons. hopefully it will work.
- if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) {
- idx = cnt;
- break;
- }
- }
- if (0xcdcdcdcd == idx) {
- DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
- }
-
- // Now continue and read all material indices
- cnt = (uint16_t)stream->GetI2();
- for (unsigned int i = 0; i < cnt;++i) {
- unsigned int fidx = (uint16_t)stream->GetI2();
-
- // check range
- if (fidx >= mMesh.mFaceMaterials.size()) {
- DefaultLogger::get()->error("3DS: Invalid face index in face material list");
- }
- else mMesh.mFaceMaterials[fidx] = idx;
- }}
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a mesh chunk. Here's the actual mesh data
-void Discreet3DSImporter::ParseMeshChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh& mMesh = mScene->mMeshes.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_VERTLIST:
- {
- // This is the list of all vertices in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mPositions.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- v.z = stream->GetF4();
- mMesh.mPositions.push_back(v);
- }}
- break;
- case Discreet3DS::CHUNK_TRMATRIX:
- {
- // This is the RLEATIVE transformation matrix of the current mesh. Vertices are
- // pretransformed by this matrix wonder.
- mMesh.mMat.a1 = stream->GetF4();
- mMesh.mMat.b1 = stream->GetF4();
- mMesh.mMat.c1 = stream->GetF4();
- mMesh.mMat.a2 = stream->GetF4();
- mMesh.mMat.b2 = stream->GetF4();
- mMesh.mMat.c2 = stream->GetF4();
- mMesh.mMat.a3 = stream->GetF4();
- mMesh.mMat.b3 = stream->GetF4();
- mMesh.mMat.c3 = stream->GetF4();
- mMesh.mMat.a4 = stream->GetF4();
- mMesh.mMat.b4 = stream->GetF4();
- mMesh.mMat.c4 = stream->GetF4();
- }
- break;
-
- case Discreet3DS::CHUNK_MAPLIST:
- {
- // This is the list of all UV coords in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mTexCoords.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- mMesh.mTexCoords.push_back(v);
- }}
- break;
-
- case Discreet3DS::CHUNK_FACELIST:
- {
- // This is the list of all faces in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mFaces.reserve(num);
- while (num-- > 0) {
- // 3DS faces are ALWAYS triangles
- mMesh.mFaces.push_back(D3DS::Face());
- D3DS::Face& sFace = mMesh.mFaces.back();
-
- sFace.mIndices[0] = (uint16_t)stream->GetI2();
- sFace.mIndices[1] = (uint16_t)stream->GetI2();
- sFace.mIndices[2] = (uint16_t)stream->GetI2();
-
- stream->IncPtr(2); // skip edge visibility flag
- }
-
- // Resize the material array (0xcdcdcdcd marks the default material; so if a face is
- // not referenced by a material, $$DEFAULT will be assigned to it)
- mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
-
- // Larger 3DS files could have multiple FACE chunks here
- chunkSize = stream->GetRemainingSizeToLimit();
- if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
- ParseFaceChunk();
- }
-
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a 3DS material chunk
-void Discreet3DSImporter::ParseMaterialChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_MAT_MATNAME:
-
- {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char* sz = (const char*)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
-
- if (!cnt) {
- // This may not be, we use the default name instead
- DefaultLogger::get()->error("3DS: Empty material name");
- }
- else mScene->mMaterials.back().mName = std::string(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_DIFFUSE:
- {
- // This is the diffuse material color
- aiColor3D* pc = &mScene->mMaterials.back().mDiffuse;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_SPECULAR:
- {
- // This is the specular material color
- aiColor3D* pc = &mScene->mMaterials.back().mSpecular;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_AMBIENT:
- {
- // This is the ambient material color
- aiColor3D* pc = &mScene->mMaterials.back().mAmbient;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILLUM:
- {
- // This is the emissive material color
- aiColor3D* pc = &mScene->mMaterials.back().mEmissive;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
- {
- // This is the material's transparency
- float* pcf = &mScene->mMaterials.back().mTransparency;
- *pcf = ParsePercentageChunk();
-
- // NOTE: transparency, not opacity
- if (is_qnan(*pcf))
- *pcf = 1.0f;
- else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SHADING:
- // This is the material shading mode
- mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
- break;
-
- case Discreet3DS::CHUNK_MAT_TWO_SIDE:
- // This is the two-sided flag
- mScene->mMaterials.back().mTwoSided = true;
- break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS:
- { // This is the shininess of the material
- float* pcf = &mScene->mMaterials.back().mSpecularExponent;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = 0.0f;
- else *pcf *= (float)0xFFFF;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
- { // This is the shininess strength of the material
- float* pcf = &mScene->mMaterials.back().mShininessStrength;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = 0.0f;
- else *pcf *= (float)0xffff / 100.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
- { // This is the self illumination strength of the material
- float f = ParsePercentageChunk();
- if (is_qnan(f))
- f = 0.0f;
- else f *= (float)0xFFFF / 100.0f;
- mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
- }
- break;
-
- // Parse texture chunks
- case Discreet3DS::CHUNK_MAT_TEXTURE:
- // Diffuse texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexDiffuse);
- break;
- case Discreet3DS::CHUNK_MAT_BUMPMAP:
- // Height map
- ParseTextureChunk(&mScene->mMaterials.back().sTexBump);
- break;
- case Discreet3DS::CHUNK_MAT_OPACMAP:
- // Opacity texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexOpacity);
- break;
- case Discreet3DS::CHUNK_MAT_MAT_SHINMAP:
- // Shininess map
- ParseTextureChunk(&mScene->mMaterials.back().sTexShininess);
- break;
- case Discreet3DS::CHUNK_MAT_SPECMAP:
- // Specular map
- ParseTextureChunk(&mScene->mMaterials.back().sTexSpecular);
- break;
- case Discreet3DS::CHUNK_MAT_SELFIMAP:
- // Self-illumination (emissive) map
- ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
- break;
- case Discreet3DS::CHUNK_MAT_REFLMAP:
- // Reflection map
- ParseTextureChunk(&mScene->mMaterials.back().sTexReflective);
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_MAPFILE:
- {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char* sz = (const char*)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
- pcOut->mMapName = std::string(sz,cnt);
- }
- break;
-
-
- case Discreet3DS::CHUNK_PERCENTF:
- // Manually parse the blend factor
- pcOut->mTextureBlend = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_PERCENTW:
- // Manually parse the blend factor
- pcOut->mTextureBlend = (float)((uint16_t)stream->GetI2()) / 100.0f;
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_USCALE:
- // Texture coordinate scaling in the U direction
- pcOut->mScaleU = stream->GetF4();
- if (0.0f == pcOut->mScaleU)
- {
- DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1.");
- pcOut->mScaleU = 1.0f;
- }
- break;
- case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
- // Texture coordinate scaling in the V direction
- pcOut->mScaleV = stream->GetF4();
- if (0.0f == pcOut->mScaleV)
- {
- DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1.");
- pcOut->mScaleV = 1.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
- // Texture coordinate offset in the U direction
- pcOut->mOffsetU = -stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
- // Texture coordinate offset in the V direction
- pcOut->mOffsetV = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_ANG:
- // Texture coordinate rotation, CCW in DEGREES
- pcOut->mRotation = -AI_DEG_TO_RAD( stream->GetF4() );
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_TILING:
- {
- const uint16_t iFlags = stream->GetI2();
-
- // Get the mapping mode (for both axes)
- if (iFlags & 0x2u)
- pcOut->mMapMode = aiTextureMapMode_Mirror;
-
- else if (iFlags & 0x10u)
- pcOut->mMapMode = aiTextureMapMode_Decal;
-
- // wrapping in all remaining cases
- else pcOut->mMapMode = aiTextureMapMode_Wrap;
- }
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a percentage chunk
-float Discreet3DSImporter::ParsePercentageChunk()
-{
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
-
- if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
- return stream->GetF4();
- else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
- return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF;
- return get_qnan();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
-void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
- bool acceptPercent)
-{
- ai_assert(out != NULL);
-
- // error return value
- const float qnan = get_qnan();
- static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
-
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
- const unsigned int diff = chunk.Size - sizeof(Discreet3DS::Chunk);
-
- // Get the type of the chunk
- switch(chunk.Flag)
- {
- case Discreet3DS::CHUNK_LINRGBF:
- case Discreet3DS::CHUNK_RGBF:
- if (sizeof(float) * 3 > diff) {
- *out = clrError;
- return;
- }
- out->r = stream->GetF4();
- out->g = stream->GetF4();
- out->b = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_LINRGBB:
- case Discreet3DS::CHUNK_RGBB:
- if (sizeof(char) * 3 > diff) {
- *out = clrError;
- return;
- }
- out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
- out->g = (float)(uint8_t)stream->GetI1() / 255.0f;
- out->b = (float)(uint8_t)stream->GetI1() / 255.0f;
- break;
-
- // Percentage chunks are accepted, too.
- case Discreet3DS::CHUNK_PERCENTF:
- if (acceptPercent && 4 <= diff) {
- out->g = out->b = out->r = stream->GetF4();
- break;
- }
- *out = clrError;
- return;
-
- case Discreet3DS::CHUNK_PERCENTW:
- if (acceptPercent && 1 <= diff) {
- out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
- break;
- }
- *out = clrError;
- return;
-
- default:
- stream->IncPtr(diff);
- // Skip unknown chunks, hope this won't cause any problems.
- return ParseColorChunk(out,acceptPercent);
- };
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/3rdparty/assimp/code/3DSLoader.h b/3rdparty/assimp/code/3DSLoader.h
deleted file mode 100644
index 3fd3aee3..00000000
--- a/3rdparty/assimp/code/3DSLoader.h
+++ /dev/null
@@ -1,280 +0,0 @@
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file 3DSLoader.h
- * @brief 3DS File format loader
- */
-#ifndef AI_3DSIMPORTER_H_INC
-#define AI_3DSIMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-struct aiNode;
-#include "3DSHelper.h"
-
-namespace Assimp {
-class MaterialHelper;
-
-using namespace D3DS;
-
-// ---------------------------------------------------------------------------------
-/** Importer class for 3D Studio r3 and r4 3DS files
- */
-class Discreet3DSImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- Discreet3DSImporter();
-
- /** Destructor, private as well */
- ~Discreet3DSImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Converts a temporary material to the outer representation
- */
- void ConvertMaterial(D3DS::Material& p_cMat,
- MaterialHelper& p_pcOut);
-
- // -------------------------------------------------------------------
- /** Read a chunk
- *
- * @param pcOut Receives the current chunk
- */
- void ReadChunk(Discreet3DS::Chunk* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a percentage chunk. mCurrent will point to the next
- * chunk behind afterwards. If no percentage chunk is found
- * QNAN is returned.
- */
- float ParsePercentageChunk();
-
- // -------------------------------------------------------------------
- /** Parse a color chunk. mCurrent will point to the next
- * chunk behind afterwards. If no color chunk is found
- * QNAN is returned in all members.
- */
- void ParseColorChunk(aiColor3D* p_pcOut,
- bool p_bAcceptPercent = true);
-
-
- // -------------------------------------------------------------------
- /** Skip a chunk in the file
- */
- void SkipChunk();
-
- // -------------------------------------------------------------------
- /** Generate the nodegraph
- */
- void GenerateNodeGraph(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a main top-level chunk in the file
- */
- void ParseMainChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level chunk in the file
- */
- void ParseChunk(const char* name, unsigned int num);
-
- // -------------------------------------------------------------------
- /** Parse a top-level editor chunk in the file
- */
- void ParseEditorChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level object chunk in the file
- */
- void ParseObjectChunk();
-
- // -------------------------------------------------------------------
- /** Parse a material chunk in the file
- */
- void ParseMaterialChunk();
-
- // -------------------------------------------------------------------
- /** Parse a mesh chunk in the file
- */
- void ParseMeshChunk();
-
- // -------------------------------------------------------------------
- /** Parse a light chunk in the file
- */
- void ParseLightChunk();
-
- // -------------------------------------------------------------------
- /** Parse a camera chunk in the file
- */
- void ParseCameraChunk();
-
- // -------------------------------------------------------------------
- /** Parse a face list chunk in the file
- */
- void ParseFaceChunk();
-
- // -------------------------------------------------------------------
- /** Parse a keyframe chunk in the file
- */
- void ParseKeyframeChunk();
-
- // -------------------------------------------------------------------
- /** Parse a hierarchy chunk in the file
- */
- void ParseHierarchyChunk(uint16_t parent);
-
- // -------------------------------------------------------------------
- /** Parse a texture chunk in the file
- */
- void ParseTextureChunk(D3DS::Texture* pcOut);
-
- // -------------------------------------------------------------------
- /** Convert the meshes in the file
- */
- void ConvertMeshes(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Replace the default material in the scene
- */
- void ReplaceDefaultMaterial();
-
- // -------------------------------------------------------------------
- /** Convert the whole scene
- */
- void ConvertScene(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** generate unique vertices for a mesh
- */
- void MakeUnique(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Add a node to the node graph
- */
- void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
- aiMatrix4x4& absTrafo);
-
- // -------------------------------------------------------------------
- /** Search for a node in the graph.
- * Called recursively
- */
- void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
-
- // -------------------------------------------------------------------
- /** Apply the master scaling factor to the mesh
- */
- void ApplyMasterScale(aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Clamp all indices in the file to a valid range
- */
- void CheckIndices(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Skip the TCB info in a track key
- */
- void SkipTCBInfo();
-
-protected:
-
- /** Stream to read from */
- StreamReaderLE* stream;
-
- /** Last touched node index */
- short mLastNodeIndex;
-
- /** Current node, root node */
- D3DS::Node* mCurrentNode, *mRootNode;
-
- /** Scene under construction */
- D3DS::Scene* mScene;
-
- /** Ambient base color of the scene */
- aiColor3D mClrAmbient;
-
- /** Master scaling factor of the scene */
- float mMasterScale;
-
- /** Path to the background image of the scene */
- std::string mBackgroundImage;
- bool bHasBG;
-
- /** true if PRJ file */
- bool bIsPrj;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/ACLoader.cpp b/3rdparty/assimp/code/ACLoader.cpp
deleted file mode 100644
index 318e2bfe..00000000
--- a/3rdparty/assimp/code/ACLoader.cpp
+++ /dev/null
@@ -1,856 +0,0 @@
-
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the AC3D importer class */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-
-// internal headers
-#include "ACLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "Subdivision.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// skip to the next token
-#define AI_AC_SKIP_TO_NEXT_TOKEN() \
- if (!SkipSpaces(&buffer)) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \
- continue; \
- }
-
-// ------------------------------------------------------------------------------------------------
-// read a string (may be enclosed in double quotation marks). buffer must point to "
-#define AI_AC_GET_STRING(out) \
- ++buffer; \
- const char* sz = buffer; \
- while ('\"' != *buffer) \
- { \
- if (IsLineEnd( *buffer )) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \
- out = "ERROR"; \
- break; \
- } \
- ++buffer; \
- } \
- if (IsLineEnd( *buffer ))continue; \
- out = std::string(sz,(unsigned int)(buffer-sz)); \
- ++buffer;
-
-
-// ------------------------------------------------------------------------------------------------
-// read 1 to n floats prefixed with an optional predefined identifier
-#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \
- AI_AC_SKIP_TO_NEXT_TOKEN(); \
- if (name_length) \
- { \
- if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \
- continue; \
- } \
- buffer += name_length+1; \
- } \
- for (unsigned int i = 0; i < num;++i) \
- { \
- AI_AC_SKIP_TO_NEXT_TOKEN(); \
- buffer = fast_atof_move(buffer,((float*)out)[i]); \
- }
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-AC3DImporter::AC3DImporter()
-{
- // nothing to be done here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-AC3DImporter::~AC3DImporter()
-{
- // nothing to be done here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
-
- // fixme: are acc and ac3d *really* used? Some sources say they are
- if (extension == "ac" || extension == "ac3d" || extension == "acc") {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint32_t token = AI_MAKE_MAGIC("AC3D");
- return CheckMagicToken(pIOHandler,pFile,&token,1,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of file extensions handled by this loader
-void AC3DImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ac");
- extensions.insert("acc");
- extensions.insert("ac3d");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a pointer to the next line from the file
-bool AC3DImporter::GetNextLine( )
-{
- SkipLine(&buffer);
- return SkipSpaces(&buffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse an object section in an AC file
-void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
-{
- if (!TokenMatch(buffer,"OBJECT",6))
- return;
-
- SkipSpaces(&buffer);
-
- ++mNumMeshes;
-
- objects.push_back(Object());
- Object& obj = objects.back();
-
- aiLight* light = NULL;
- if (!ASSIMP_strincmp(buffer,"light",5))
- {
- // This is a light source. Add it to the list
- mLights->push_back(light = new aiLight());
-
- // Return a point light with no attenuation
- light->mType = aiLightSource_POINT;
- light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f);
- light->mAttenuationConstant = 1.f;
-
- // Generate a default name for both the light source and the node
- // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
- light->mName.length = ::sprintf(light->mName.data,"ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
- obj.name = std::string( light->mName.data );
-
- DefaultLogger::get()->debug("AC3D: Light source encountered");
- obj.type = Object::Light;
- }
- else if (!ASSIMP_strincmp(buffer,"group",5))
- {
- obj.type = Object::Group;
- }
- else if (!ASSIMP_strincmp(buffer,"world",5))
- {
- obj.type = Object::World;
- }
- else obj.type = Object::Poly;
- while (GetNextLine())
- {
- if (TokenMatch(buffer,"kids",4))
- {
- SkipSpaces(&buffer);
- unsigned int num = strtol10(buffer,&buffer);
- GetNextLine();
- if (num)
- {
- // load the children of this object recursively
- obj.children.reserve(num);
- for (unsigned int i = 0; i < num; ++i)
- LoadObjectSection(obj.children);
- }
- return;
- }
- else if (TokenMatch(buffer,"name",4))
- {
- SkipSpaces(&buffer);
- AI_AC_GET_STRING(obj.name);
-
- // If this is a light source, we'll also need to store
- // the name of the node in it.
- if (light)
- {
- light->mName.Set(obj.name);
- }
- }
- else if (TokenMatch(buffer,"texture",7))
- {
- SkipSpaces(&buffer);
- AI_AC_GET_STRING(obj.texture);
- }
- else if (TokenMatch(buffer,"texrep",6))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat);
- if (!obj.texRepeat.x || !obj.texRepeat.y)
- obj.texRepeat = aiVector2D (1.f,1.f);
- }
- else if (TokenMatch(buffer,"texoff",6))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset);
- }
- else if (TokenMatch(buffer,"rot",3))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation);
- }
- else if (TokenMatch(buffer,"loc",3))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation);
- }
- else if (TokenMatch(buffer,"subdiv",6))
- {
- SkipSpaces(&buffer);
- obj.subDiv = strtol10(buffer,&buffer);
- }
- else if (TokenMatch(buffer,"crease",6))
- {
- SkipSpaces(&buffer);
- obj.crease = fast_atof(buffer);
- }
- else if (TokenMatch(buffer,"numvert",7))
- {
- SkipSpaces(&buffer);
-
- unsigned int t = strtol10(buffer,&buffer);
- obj.vertices.reserve(t);
- for (unsigned int i = 0; i < t;++i)
- {
- if (!GetNextLine())
- {
- DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet");
- break;
- }
- else if (!IsNumeric(*buffer))
- {
- DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet");
- --buffer; // make sure the line is processed a second time
- break;
- }
- obj.vertices.push_back(aiVector3D());
- aiVector3D& v = obj.vertices.back();
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
- }
- }
- else if (TokenMatch(buffer,"numsurf",7))
- {
- SkipSpaces(&buffer);
-
- bool Q3DWorkAround = false;
-
- const unsigned int t = strtol10(buffer,&buffer);
- obj.surfaces.reserve(t);
- for (unsigned int i = 0; i < t;++i)
- {
- GetNextLine();
- if (!TokenMatch(buffer,"SURF",4))
- {
- // FIX: this can occur for some files - Quick 3D for
- // example writes no surf chunks
- if (!Q3DWorkAround)
- {
- DefaultLogger::get()->warn("AC3D: SURF token was expected");
- DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled");
- }
- --buffer; // make sure the line is processed a second time
- // break; --- see fix notes above
-
- Q3DWorkAround = true;
- }
- SkipSpaces(&buffer);
- obj.surfaces.push_back(Surface());
- Surface& surf = obj.surfaces.back();
- surf.flags = strtol_cppstyle(buffer);
-
- while (1)
- {
- if (!GetNextLine())
- {
- DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete");
- break;
- }
- if (TokenMatch(buffer,"mat",3))
- {
- SkipSpaces(&buffer);
- surf.mat = strtol10(buffer);
- }
- else if (TokenMatch(buffer,"refs",4))
- {
- // --- see fix notes above
- if (Q3DWorkAround)
- {
- if (!surf.entries.empty())
- {
- buffer -= 6;
- break;
- }
- }
-
- SkipSpaces(&buffer);
- const unsigned int m = strtol10(buffer);
- surf.entries.reserve(m);
-
- obj.numRefs += m;
-
- for (unsigned int k = 0; k < m; ++k)
- {
- if (!GetNextLine())
- {
- DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete");
- break;
- }
- surf.entries.push_back(Surface::SurfaceEntry());
- Surface::SurfaceEntry& entry = surf.entries.back();
-
- entry.first = strtol10(buffer,&buffer);
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second);
- }
- }
- else
- {
-
- --buffer; // make sure the line is processed a second time
- break;
- }
- }
- }
- }
- }
- DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a material from AC3DImporter::Material to aiMaterial
-void AC3DImporter::ConvertMaterial(const Object& object,
- const Material& matSrc,
- MaterialHelper& matDest)
-{
- aiString s;
-
- if (matSrc.name.length())
- {
- s.Set(matSrc.name);
- matDest.AddProperty(&s,AI_MATKEY_NAME);
- }
- if (object.texture.length())
- {
- s.Set(object.texture);
- matDest.AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // UV transformation
- if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y ||
- object.texOffset.x || object.texOffset.y)
- {
- aiUVTransform transform;
- transform.mScaling = object.texRepeat;
- transform.mTranslation = object.texOffset;
- matDest.AddProperty(&transform,1,AI_MATKEY_UVTRANSFORM_DIFFUSE(0));
- }
- }
-
- matDest.AddProperty<aiColor3D>(&matSrc.rgb,1, AI_MATKEY_COLOR_DIFFUSE);
- matDest.AddProperty<aiColor3D>(&matSrc.amb,1, AI_MATKEY_COLOR_AMBIENT);
- matDest.AddProperty<aiColor3D>(&matSrc.emis,1,AI_MATKEY_COLOR_EMISSIVE);
- matDest.AddProperty<aiColor3D>(&matSrc.spec,1,AI_MATKEY_COLOR_SPECULAR);
-
- int n;
- if (matSrc.shin)
- {
- n = aiShadingMode_Phong;
- matDest.AddProperty<float>(&matSrc.shin,1,AI_MATKEY_SHININESS);
- }
- else n = aiShadingMode_Gouraud;
- matDest.AddProperty<int>(&n,1,AI_MATKEY_SHADING_MODEL);
-
- float f = 1.f - matSrc.trans;
- matDest.AddProperty<float>(&f,1,AI_MATKEY_OPACITY);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the loaded data to the internal verbose representation
-aiNode* AC3DImporter::ConvertObjectSection(Object& object,
- std::vector<aiMesh*>& meshes,
- std::vector<MaterialHelper*>& outMaterials,
- const std::vector<Material>& materials,
- aiNode* parent)
-{
- aiNode* node = new aiNode();
- node->mParent = parent;
- if (object.vertices.size())
- {
- if (!object.surfaces.size() || !object.numRefs)
- {
- /* " An object with 7 vertices (no surfaces, no materials defined).
- This is a good way of getting point data into AC3D.
- The Vertex->create convex-surface/object can be used on these
- vertices to 'wrap' a 3d shape around them "
- (http://www.opencity.info/html/ac3dfileformat.html)
-
- therefore: if no surfaces are defined return point data only
- */
-
- DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, "
- "a point list is returned");
-
- meshes.push_back(new aiMesh());
- aiMesh* mesh = meshes.back();
-
- mesh->mNumFaces = mesh->mNumVertices = (unsigned int)object.vertices.size();
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
-
- for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts)
- {
- *verts = object.vertices[i];
- faces->mNumIndices = 1;
- faces->mIndices = new unsigned int[1];
- faces->mIndices[0] = i;
- }
-
- // use the primary material in this case. this should be the
- // default material if all objects of the file contain points
- // and no faces.
- mesh->mMaterialIndex = 0;
- outMaterials.push_back(new MaterialHelper());
- ConvertMaterial(object, materials[0], *outMaterials.back());
- }
- else
- {
- // need to generate one or more meshes for this object.
- // find out how many different materials we have
- typedef std::pair< unsigned int, unsigned int > IntPair;
- typedef std::vector< IntPair > MatTable;
- MatTable needMat(materials.size(),IntPair(0,0));
-
- std::vector<Surface>::iterator it,end = object.surfaces.end();
- std::vector<Surface::SurfaceEntry>::iterator it2,end2;
-
- for (it = object.surfaces.begin(); it != end; ++it)
- {
- register unsigned int idx = (*it).mat;
- if (idx >= needMat.size())
- {
- DefaultLogger::get()->error("AC3D: material index is out of range");
- idx = 0;
- }
- if ((*it).entries.empty())
- {
- DefaultLogger::get()->warn("AC3D: surface her zero vertex references");
- }
-
- // validate all vertex indices to make sure we won't crash here
- for (it2 = (*it).entries.begin(),
- end2 = (*it).entries.end(); it2 != end2; ++it2)
- {
- if ((*it2).first >= object.vertices.size())
- {
- DefaultLogger::get()->warn("AC3D: Invalid vertex reference");
- (*it2).first = 0;
- }
- }
-
- if (!needMat[idx].first)++node->mNumMeshes;
-
- switch ((*it).flags & 0xf)
- {
- // closed line
- case 0x1:
-
- needMat[idx].first += (unsigned int)(*it).entries.size();
- needMat[idx].second += (unsigned int)(*it).entries.size()<<1u;
- break;
-
- // unclosed line
- case 0x2:
-
- needMat[idx].first += (unsigned int)(*it).entries.size()-1;
- needMat[idx].second += ((unsigned int)(*it).entries.size()-1)<<1u;
- break;
-
- // 0 == polygon, else unknown
- default:
-
- if ((*it).flags & 0xf)
- {
- DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown");
- (*it).flags &= ~(0xf);
- }
-
- // the number of faces increments by one, the number
- // of vertices by surface.numref.
- needMat[idx].first++;
- needMat[idx].second += (unsigned int)(*it).entries.size();
- };
- }
- unsigned int* pip = node->mMeshes = new unsigned int[node->mNumMeshes];
- unsigned int mat = 0;
- const size_t oldm = meshes.size();
- for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
- cit != cend; ++cit, ++mat)
- {
- if (!(*cit).first)continue;
-
- // allocate a new aiMesh object
- *pip++ = (unsigned int)meshes.size();
- aiMesh* mesh = new aiMesh();
- meshes.push_back(mesh);
-
- mesh->mMaterialIndex = (unsigned int)outMaterials.size();
- outMaterials.push_back(new MaterialHelper());
- ConvertMaterial(object, materials[mat], *outMaterials.back());
-
- // allocate storage for vertices and normals
- mesh->mNumFaces = (*cit).first;
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- mesh->mNumVertices = (*cit).second;
- aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- unsigned int cur = 0;
-
- // allocate UV coordinates, but only if the texture name for the
- // surface is not empty
- aiVector3D* uv = NULL;
- if (object.texture.length())
- {
- uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
- }
-
- for (it = object.surfaces.begin(); it != end; ++it)
- {
- if (mat == (*it).mat)
- {
- const Surface& src = *it;
-
- // closed polygon
- unsigned int type = (*it).flags & 0xf;
- if (!type)
- {
- aiFace& face = *faces++;
- if ((face.mNumIndices = (unsigned int)src.entries.size()))
- {
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices)
- {
- const Surface::SurfaceEntry& entry = src.entries[i];
- face.mIndices[i] = cur++;
-
- // copy vertex positions
- *vertices = object.vertices[entry.first] + object.translation;
-
-
- // copy texture coordinates
- if (uv)
- {
- uv->x = entry.second.x;
- uv->y = entry.second.y;
- ++uv;
- }
- }
- }
- }
- else
- {
-
- it2 = (*it).entries.begin();
-
- // either a closed or an unclosed line
- register unsigned int tmp = (unsigned int)(*it).entries.size();
- if (0x2 == type)--tmp;
- for (unsigned int m = 0; m < tmp;++m)
- {
- aiFace& face = *faces++;
-
- face.mNumIndices = 2;
- face.mIndices = new unsigned int[2];
- face.mIndices[0] = cur++;
- face.mIndices[1] = cur++;
-
- // copy vertex positions
- *vertices++ = object.vertices[(*it2).first];
-
- // copy texture coordinates
- if (uv)
- {
- uv->x = (*it2).second.x;
- uv->y = (*it2).second.y;
- ++uv;
- }
-
-
- if (0x1 == type && tmp-1 == m)
- {
- // if this is a closed line repeat its beginning now
- it2 = (*it).entries.begin();
- }
- else ++it2;
-
- // second point
- *vertices++ = object.vertices[(*it2).first];
-
- if (uv)
- {
- uv->x = (*it2).second.x;
- uv->y = (*it2).second.y;
- ++uv;
- }
- }
- }
- }
- }
- }
-
- // Now apply catmull clark subdivision if necessary. We split meshes into
- // materials which is not done by AC3D during smoothing, so we need to
- // collect all meshes using the same material group.
- if (object.subDiv) {
- if (configEvalSubdivision) {
- boost::scoped_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
- DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
-
- std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
- div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true);
- std::copy(cpy.begin(),cpy.end(),meshes.begin()+oldm);
-
- // previous meshes are deleted vy Subdivide().
- }
- else {
- DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: "
- +object.name);
- }
- }
- }
- }
-
- if (object.name.length())
- node->mName.Set(object.name);
- else
- {
- // generate a name depending on the type of the node
- switch (object.type)
- {
- case Object::Group:
- node->mName.length = ::sprintf(node->mName.data,"ACGroup_%i",groups++);
- break;
- case Object::Poly:
- node->mName.length = ::sprintf(node->mName.data,"ACPoly_%i",polys++);
- break;
- case Object::Light:
- node->mName.length = ::sprintf(node->mName.data,"ACLight_%i",lights++);
- break;
-
- // there shouldn't be more than one world, but we don't care
- case Object::World:
- node->mName.length = ::sprintf(node->mName.data,"ACWorld_%i",worlds++);
- break;
- }
- }
-
-
- // setup the local transformation matrix of the object
- // compute the transformation offset to the parent node
- node->mTransformation = aiMatrix4x4 ( object.rotation );
-
- if (object.type == Object::Group || !object.numRefs)
- {
- node->mTransformation.a4 = object.translation.x;
- node->mTransformation.b4 = object.translation.y;
- node->mTransformation.c4 = object.translation.z;
- }
-
- // add children to the object
- if (object.children.size())
- {
- node->mNumChildren = (unsigned int)object.children.size();
- node->mChildren = new aiNode*[node->mNumChildren];
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- {
- node->mChildren[i] = ConvertObjectSection(object.children[i],meshes,outMaterials,materials,node);
- }
- }
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-void AC3DImporter::SetupProperties(const Importer* pImp)
-{
- configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL,1) ? true : false;
- configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION,1) ? true : false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void AC3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open AC3D file " + pFile + ".");
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- buffer = &mBuffer2[0];
- mNumMeshes = 0;
-
- lights = polys = worlds = groups = 0;
-
- if (::strncmp(buffer,"AC3D",4)) {
- throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
- }
-
- // print the file format version to the console
- unsigned int version = HexDigitToDecimal( buffer[4] );
- char msg[3];
- ASSIMP_itoa10(msg,3,version);
- DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
-
- std::vector<Material> materials;
- materials.reserve(5);
-
- std::vector<Object> rootObjects;
- rootObjects.reserve(5);
-
- std::vector<aiLight*> lights;
- mLights = & lights;
-
- while (GetNextLine())
- {
- if (TokenMatch(buffer,"MATERIAL",8))
- {
- materials.push_back(Material());
- Material& mat = materials.back();
-
- // manually parse the material ... sscanf would use the buldin atof ...
- // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
-
- AI_AC_SKIP_TO_NEXT_TOKEN();
- if ('\"' == *buffer)
- {
- AI_AC_GET_STRING(mat.name);
- AI_AC_SKIP_TO_NEXT_TOKEN();
- }
-
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans);
- }
- LoadObjectSection(rootObjects);
- }
-
- if (rootObjects.empty() || !mNumMeshes)
- {
- throw DeadlyImportError("AC3D: No meshes have been loaded");
- }
- if (materials.empty())
- {
- DefaultLogger::get()->warn("AC3D: No material has been found");
- materials.push_back(Material());
- }
-
- mNumMeshes += (mNumMeshes>>2u) + 1;
- std::vector<aiMesh*> meshes;
- meshes.reserve(mNumMeshes);
-
- std::vector<MaterialHelper*> omaterials;
- materials.reserve(mNumMeshes);
-
- // generate a dummy root if there are multiple objects on the top layer
- Object* root;
- if (1 == rootObjects.size())
- root = &rootObjects[0];
- else
- {
- root = new Object();
- }
-
- // now convert the imported stuff to our output data structure
- pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials);
- if (1 != rootObjects.size())delete root;
-
- if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4))
- pScene->mRootNode->mName.Set("<AC3DWorld>");
-
- // copy meshes
- if (meshes.empty())
- {
- throw DeadlyImportError("An unknown error occured during converting");
- }
- pScene->mNumMeshes = (unsigned int)meshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- ::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*));
-
- // copy materials
- pScene->mNumMaterials = (unsigned int)omaterials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- ::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*));
-
- // copy lights
- pScene->mNumLights = (unsigned int)lights.size();
- if (lights.size())
- {
- pScene->mLights = new aiLight*[lights.size()];
- ::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*));
- }
-}
-
-#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
diff --git a/3rdparty/assimp/code/ACLoader.h b/3rdparty/assimp/code/ACLoader.h
deleted file mode 100644
index 0f994710..00000000
--- a/3rdparty/assimp/code/ACLoader.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file ACLoader.h
- * @brief Declaration of the .ac importer class.
- */
-#ifndef AI_AC3DLOADER_H_INCLUDED
-#define AI_AC3DLOADER_H_INCLUDED
-
-#include <vector>
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** AC3D (*.ac) importer class
-*/
-class AC3DImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- AC3DImporter();
-
- /** Destructor, private as well */
- ~AC3DImporter();
-
-
- // Represents an AC3D material
- struct Material
- {
- Material()
- : rgb (0.6f,0.6f,0.6f)
- , spec (1.f,1.f,1.f)
- , shin (0.f)
- , trans (0.f)
- {}
-
- // base color of the material
- aiColor3D rgb;
-
- // ambient color of the material
- aiColor3D amb;
-
- // emissive color of the material
- aiColor3D emis;
-
- // specular color of the material
- aiColor3D spec;
-
- // shininess exponent
- float shin;
-
- // transparency. 0 == opaque
- float trans;
-
- // name of the material. optional.
- std::string name;
- };
-
- // Represents an AC3D surface
- struct Surface
- {
- Surface()
- : mat (0)
- , flags (0)
- {}
-
- unsigned int mat,flags;
-
- typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
- std::vector< SurfaceEntry > entries;
- };
-
- // Represents an AC3D object
- struct Object
- {
- Object()
- : type (World)
- , name( "" )
- , children()
- , texture( "" )
- , texRepeat( 1.f, 1.f )
- , texOffset( 0.0f, 0.0f )
- , rotation()
- , translation()
- , vertices()
- , surfaces()
- , numRefs (0)
- , subDiv (0)
- {}
-
- // Type description
- enum Type
- {
- World = 0x0,
- Poly = 0x1,
- Group = 0x2,
- Light = 0x4
- } type;
-
- // name of the object
- std::string name;
-
- // object children
- std::vector<Object> children;
-
- // texture to be assigned to all surfaces of the object
- std::string texture;
-
- // texture repat factors (scaling for all coordinates)
- aiVector2D texRepeat, texOffset;
-
- // rotation matrix
- aiMatrix3x3 rotation;
-
- // translation vector
- aiVector3D translation;
-
- // vertices
- std::vector<aiVector3D> vertices;
-
- // surfaces
- std::vector<Surface> surfaces;
-
- // number of indices (= num verts in verbose format)
- unsigned int numRefs;
-
- // number of subdivisions to be performed on the
- // imported data
- unsigned int subDiv;
-
- // max angle limit for smoothing
- float crease;
- };
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details*/
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.*/
- void SetupProperties(const Importer* pImp);
-
-private:
-
- // -------------------------------------------------------------------
- /** Get the next line from the file.
- * @return false if the end of the file was reached*/
- bool GetNextLine();
-
- // -------------------------------------------------------------------
- /** Load the object section. This method is called recursively to
- * load subobjects, the method returns after a 'kids 0' was
- * encountered.
- * @objects List of output objects*/
- void LoadObjectSection(std::vector<Object>& objects);
-
- // -------------------------------------------------------------------
- /** Convert all objects into meshes and nodes.
- * @param object Current object to work on
- * @param meshes Pointer to the list of output meshes
- * @param outMaterials List of output materials
- * @param materials Material list
- * @param Scenegraph node for the object */
- aiNode* ConvertObjectSection(Object& object,
- std::vector<aiMesh*>& meshes,
- std::vector<MaterialHelper*>& outMaterials,
- const std::vector<Material>& materials,
- aiNode* parent = NULL);
-
- // -------------------------------------------------------------------
- /** Convert a material
- * @param object Current object
- * @param matSrc Source material description
- * @param matDest Destination material to be filled */
- void ConvertMaterial(const Object& object,
- const Material& matSrc,
- MaterialHelper& matDest);
-
-private:
-
-
- // points to the next data line
- const char* buffer;
-
- // Configuration option: if enabled, up to two meshes
- // are generated per material: those faces who have
- // their bf cull flags set are separated.
- bool configSplitBFCull;
-
- // Configuration switch: subdivision surfaces are only
- // evaluated if the value is true.
- bool configEvalSubdivision;
-
- // counts how many objects we have in the tree.
- // basing on this information we can find a
- // good estimate how many meshes we'll have in the final scene.
- unsigned int mNumMeshes;
-
- // current list of light sources
- std::vector<aiLight*>* mLights;
-
- // name counters
- unsigned int lights, groups, polys, worlds;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_AC3DIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/ASELoader.cpp b/3rdparty/assimp/code/ASELoader.cpp
deleted file mode 100644
index 6f63c894..00000000
--- a/3rdparty/assimp/code/ASELoader.cpp
+++ /dev/null
@@ -1,1302 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file ASELoader.cpp
- * @brief Implementation of the ASE importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-
-// internal headers
-#include "ASELoader.h"
-#include "MaterialSystem.h"
-#include "StringComparison.h"
-#include "SkeletonMeshBuilder.h"
-#include "TargetAnimation.h"
-
-// utilities
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace Assimp::ASE;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ASEImporter::ASEImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ASEImporter::~ASEImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if ( extension == "ase" || extension == "ask")
- return true;
-
- if ((!extension.length() || cs) && pIOHandler) {
- const char* tokens[] = {"*3dsmax_asciiexport"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ase");
- extensions.insert("ask");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration options
-void ASEImporter::SetupProperties(const Importer* pImp)
-{
- configRecomputeNormals = (pImp->GetPropertyInteger(
- AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void ASEImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- this->mBuffer = &mBuffer2[0];
- this->pcScene = pScene;
-
- // ------------------------------------------------------------------
- // Guess the file format by looking at the extension
- // ASC is considered to be the older format 110,
- // ASE is the actual version 200 (that is currently written by max)
- // ------------------------------------------------------------------
- unsigned int defaultFormat;
- std::string::size_type s = pFile.length()-1;
- switch (pFile.c_str()[s]) {
-
- case 'C':
- case 'c':
- defaultFormat = AI_ASE_OLD_FILE_FORMAT;
- break;
- default:
- defaultFormat = AI_ASE_NEW_FILE_FORMAT;
- };
-
- // Construct an ASE parser and parse the file
- ASE::Parser parser(mBuffer,defaultFormat);
- mParser = &parser;
- mParser->Parse();
-
- //------------------------------------------------------------------
- // Check whether we god at least one mesh. If we did - generate
- // materials and copy meshes.
- // ------------------------------------------------------------------
- if ( !mParser->m_vMeshes.empty()) {
-
- // If absolutely no material has been loaded from the file
- // we need to generate a default material
- GenerateDefaultMaterial();
-
- // process all meshes
- bool tookNormals = false;
- std::vector<aiMesh*> avOutMeshes;
- avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
- for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
- if ((*i).bSkip) {
- continue;
- }
- BuildUniqueRepresentation(*i);
-
- // Need to generate proper vertex normals if necessary
- if (GenerateNormals(*i)) {
- tookNormals = true;
- }
-
- // Convert all meshes to aiMesh objects
- ConvertMeshes(*i,avOutMeshes);
- }
- if (tookNormals) {
- DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
- "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you "
- "experience problems");
- }
-
- // Now build the output mesh list. Remove dummies
- pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
- aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (std::vector<aiMesh*>::const_iterator i = avOutMeshes.begin();i != avOutMeshes.end();++i) {
- if (!(*i)->mNumFaces) {
- continue;
- }
- *pp++ = *i;
- }
- pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
-
- // Build final material indices (remove submaterials and setup
- // the final list)
- BuildMaterialIndices();
- }
-
- // ------------------------------------------------------------------
- // Copy all scene graph nodes - lights, cameras, dummies and meshes
- // into one huge list.
- //------------------------------------------------------------------
- std::vector<BaseNode*> nodes;
- nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size()
- + mParser->m_vCameras.size() + mParser->m_vDummies.size());
-
- // Lights
- for (std::vector<ASE::Light>::iterator it = mParser->m_vLights.begin(),
- end = mParser->m_vLights.end();it != end; ++it)nodes.push_back(&(*it));
- // Cameras
- for (std::vector<ASE::Camera>::iterator it = mParser->m_vCameras.begin(),
- end = mParser->m_vCameras.end();it != end; ++it)nodes.push_back(&(*it));
- // Meshes
- for (std::vector<ASE::Mesh>::iterator it = mParser->m_vMeshes.begin(),
- end = mParser->m_vMeshes.end();it != end; ++it)nodes.push_back(&(*it));
- // Dummies
- for (std::vector<ASE::Dummy>::iterator it = mParser->m_vDummies.begin(),
- end = mParser->m_vDummies.end();it != end; ++it)nodes.push_back(&(*it));
-
- // build the final node graph
- BuildNodes(nodes);
-
- // build output animations
- BuildAnimations(nodes);
-
- // build output cameras
- BuildCameras();
-
- // build output lights
- BuildLights();
-
- // ------------------------------------------------------------------
- // If we have no meshes use the SkeletonMeshBuilder helper class
- // to build a mesh for the animation skeleton
- // FIXME: very strange results
- // ------------------------------------------------------------------
- if (!pScene->mNumMeshes) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- SkeletonMeshBuilder skeleton(pScene);
- }
-}
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::GenerateDefaultMaterial()
-{
- ai_assert(NULL != mParser);
-
- bool bHas = false;
- for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
- if ((*i).bSkip)continue;
- if (ASE::Face::DEFAULT_MATINDEX == (*i).iMaterialIndex) {
- (*i).iMaterialIndex = (unsigned int)mParser->m_vMaterials.size();
- bHas = true;
- }
- }
- if (bHas || mParser->m_vMaterials.empty()) {
- // add a simple material without submaterials to the parser's list
- mParser->m_vMaterials.push_back ( ASE::Material() );
- ASE::Material& mat = mParser->m_vMaterials.back();
-
- mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f);
- mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
- mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
- mat.mShading = Discreet3DS::Gouraud;
- mat.mName = AI_DEFAULT_MATERIAL_NAME;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::BuildAnimations(const std::vector<BaseNode*>& nodes)
-{
- // check whether we have at least one mesh which has animations
- std::vector<ASE::BaseNode*>::const_iterator i = nodes.begin();
- unsigned int iNum = 0;
- for (;i != nodes.end();++i) {
-
- // TODO: Implement Bezier & TCB support
- if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
- if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
- if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
-
- // We compare against 1 here - firstly one key is not
- // really an animation and secondly MAX writes dummies
- // that represent the node transformation.
- if ((*i)->mAnim.akeyPositions.size()>1 || (*i)->mAnim.akeyRotations.size()>1 || (*i)->mAnim.akeyScaling.size()>1){
- ++iNum;
- }
- if ((*i)->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( (*i)->mTargetPosition.x )) {
- ++iNum;
- }
- }
- if (iNum) {
- // Generate a new animation channel and setup everything for it
- pcScene->mNumAnimations = 1;
- pcScene->mAnimations = new aiAnimation*[1];
- aiAnimation* pcAnim = pcScene->mAnimations[0] = new aiAnimation();
- pcAnim->mNumChannels = iNum;
- pcAnim->mChannels = new aiNodeAnim*[iNum];
- pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame;
-
- iNum = 0;
-
- // Now iterate through all meshes and collect all data we can find
- for (i = nodes.begin();i != nodes.end();++i) {
-
- ASE::BaseNode* me = *i;
- if ( me->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( me->mTargetPosition.x )) {
- // Generate an extra channel for the camera/light target.
- // BuildNodes() does also generate an extra node, named
- // <baseName>.Target.
- aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
- nd->mNodeName.Set(me->mName + ".Target");
-
- // If there is no input position channel we will need
- // to supply the default position from the node's
- // local transformation matrix.
- /*TargetAnimationHelper helper;
- if (me->mAnim.akeyPositions.empty())
- {
- aiMatrix4x4& mat = (*i)->mTransform;
- helper.SetFixedMainAnimationChannel(aiVector3D(
- mat.a4, mat.b4, mat.c4));
- }
- else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
- helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
-
- helper.Process(&me->mTargetAnim.akeyPositions);*/
-
- // Allocate the key array and fill it
- nd->mNumPositionKeys = (unsigned int) me->mTargetAnim.akeyPositions.size();
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
-
- ::memcpy(nd->mPositionKeys,&me->mTargetAnim.akeyPositions[0],
- nd->mNumPositionKeys * sizeof(aiVectorKey));
- }
-
- if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 || me->mAnim.akeyScaling.size() > 1) {
- // Begin a new node animation channel for this node
- aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
- nd->mNodeName.Set(me->mName);
-
- // copy position keys
- if (me->mAnim.akeyPositions.size() > 1 )
- {
- // Allocate the key array and fill it
- nd->mNumPositionKeys = (unsigned int) me->mAnim.akeyPositions.size();
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
-
- ::memcpy(nd->mPositionKeys,&me->mAnim.akeyPositions[0],
- nd->mNumPositionKeys * sizeof(aiVectorKey));
- }
- // copy rotation keys
- if (me->mAnim.akeyRotations.size() > 1 ) {
- // Allocate the key array and fill it
- nd->mNumRotationKeys = (unsigned int) me->mAnim.akeyRotations.size();
- nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
-
- // --------------------------------------------------------------------
- // Rotation keys are offsets to the previous keys.
- // We have the quaternion representations of all
- // of them, so we just need to concatenate all
- // (unit-length) quaternions to get the absolute
- // rotations.
- // Rotation keys are ABSOLUTE for older files
- // --------------------------------------------------------------------
-
- aiQuaternion cur;
- for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
- aiQuatKey q = me->mAnim.akeyRotations[a];
-
- if (mParser->iFileFormat > 110) {
- cur = (a ? cur*q.mValue : q.mValue);
- q.mValue = cur.Normalize();
- }
- nd->mRotationKeys[a] = q;
-
- // need this to get to Assimp quaternion conventions
- nd->mRotationKeys[a].mValue.w *= -1.f;
- }
- }
- // copy scaling keys
- if (me->mAnim.akeyScaling.size() > 1 ) {
- // Allocate the key array and fill it
- nd->mNumScalingKeys = (unsigned int) me->mAnim.akeyScaling.size();
- nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
-
- ::memcpy(nd->mScalingKeys,&me->mAnim.akeyScaling[0],
- nd->mNumScalingKeys * sizeof(aiVectorKey));
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output cameras
-void ASEImporter::BuildCameras()
-{
- if (!mParser->m_vCameras.empty()) {
- pcScene->mNumCameras = (unsigned int)mParser->m_vCameras.size();
- pcScene->mCameras = new aiCamera*[pcScene->mNumCameras];
-
- for (unsigned int i = 0; i < pcScene->mNumCameras;++i) {
- aiCamera* out = pcScene->mCameras[i] = new aiCamera();
- ASE::Camera& in = mParser->m_vCameras[i];
-
- // copy members
- out->mClipPlaneFar = in.mFar;
- out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
- out->mHorizontalFOV = in.mFOV;
-
- out->mName.Set(in.mName);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output lights
-void ASEImporter::BuildLights()
-{
- if (!mParser->m_vLights.empty()) {
- pcScene->mNumLights = (unsigned int)mParser->m_vLights.size();
- pcScene->mLights = new aiLight*[pcScene->mNumLights];
-
- for (unsigned int i = 0; i < pcScene->mNumLights;++i) {
- aiLight* out = pcScene->mLights[i] = new aiLight();
- ASE::Light& in = mParser->m_vLights[i];
-
- // The direction is encoded in the transformation matrix of the node.
- // In 3DS MAX the light source points into negative Z direction if
- // the node transformation is the identity.
- out->mDirection = aiVector3D(0.f,0.f,-1.f);
-
- out->mName.Set(in.mName);
- switch (in.mLightType)
- {
- case ASE::Light::TARGET:
- out->mType = aiLightSource_SPOT;
- out->mAngleInnerCone = AI_DEG_TO_RAD(in.mAngle);
- out->mAngleOuterCone = (in.mFalloff ? AI_DEG_TO_RAD(in.mFalloff) : out->mAngleInnerCone);
- break;
-
- case ASE::Light::DIRECTIONAL:
- out->mType = aiLightSource_DIRECTIONAL;
- break;
-
- default:
- //case ASE::Light::OMNI:
- out->mType = aiLightSource_POINT;
- break;
- };
- out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::AddNodes(const std::vector<BaseNode*>& nodes,
- aiNode* pcParent,const char* szName)
-{
- aiMatrix4x4 m;
- AddNodes(nodes,pcParent,szName,m);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add meshes to a given node
-void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node)
-{
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) {
- // Get the name of the mesh (the mesh instance has been temporarily stored in the third vertex color)
- const aiMesh* pcMesh = pcScene->mMeshes[i];
- const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
-
- if (mesh == snode) {
- ++node->mNumMeshes;
- }
- }
-
- if (node->mNumMeshes) {
- node->mMeshes = new unsigned int[node->mNumMeshes];
- for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i) {
-
- const aiMesh* pcMesh = pcScene->mMeshes[i];
- const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
- if (mesh == snode) {
- node->mMeshes[p++] = i;
-
- // Transform all vertices of the mesh back into their local space ->
- // at the moment they are pretransformed
- aiMatrix4x4 m = mesh->mTransform;
- m.Inverse();
-
- aiVector3D* pvCurPtr = pcMesh->mVertices;
- const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
- while (pvCurPtr != pvEndPtr) {
- *pvCurPtr = m * (*pvCurPtr);
- pvCurPtr++;
- }
-
- // Do the same for the normal vectors, if we have them.
- // As always, inverse transpose.
- if (pcMesh->mNormals) {
- aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform );
- m3.Transpose();
-
- pvCurPtr = pcMesh->mNormals;
- pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
- while (pvCurPtr != pvEndPtr) {
- *pvCurPtr = m3 * (*pvCurPtr);
- pvCurPtr++;
- }
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add child nodes to a given parent node
-void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
- aiNode* pcParent, const char* szName,
- const aiMatrix4x4& mat)
-{
- const size_t len = szName ? ::strlen(szName) : 0;
- ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
-
- // Receives child nodes for the pcParent node
- std::vector<aiNode*> apcNodes;
-
- // Now iterate through all nodes in the scene and search for one
- // which has *us* as parent.
- for (std::vector<BaseNode*>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
- const BaseNode* snode = *it;
- if (szName) {
- if (len != snode->mParent.length() || ::strcmp(szName,snode->mParent.c_str()))
- continue;
- }
- else if (snode->mParent.length())
- continue;
-
- (*it)->mProcessed = true;
-
- // Allocate a new node and add it to the output data structure
- apcNodes.push_back(new aiNode());
- aiNode* node = apcNodes.back();
-
- node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
- node->mParent = pcParent;
-
- // Setup the transformation matrix of the node
- aiMatrix4x4 mParentAdjust = mat;
- mParentAdjust.Inverse();
- node->mTransformation = mParentAdjust*snode->mTransform;
-
- // Add sub nodes - prevent stack overflow due to recursive parenting
- if (node->mName != node->mParent->mName) {
- AddNodes(nodes,node,node->mName.data,snode->mTransform);
- }
-
- // Further processing depends on the type of the node
- if (snode->mType == ASE::BaseNode::Mesh) {
- // If the type of this node is "Mesh" we need to search
- // the list of output meshes in the data structure for
- // all those that belonged to this node once. This is
- // slightly inconvinient here and a better solution should
- // be used when this code is refactored next.
- AddMeshes(snode,node);
- }
- else if (is_not_qnan( snode->mTargetPosition.x )) {
- // If this is a target camera or light we generate a small
- // child node which marks the position of the camera
- // target (the direction information is contained in *this*
- // node's animation track but the exact target position
- // would be lost otherwise)
- if (!node->mNumChildren) {
- node->mChildren = new aiNode*[1];
- }
-
- aiNode* nd = new aiNode();
-
- nd->mName.Set ( snode->mName + ".Target" );
-
- nd->mTransformation.a4 = snode->mTargetPosition.x - snode->mTransform.a4;
- nd->mTransformation.b4 = snode->mTargetPosition.y - snode->mTransform.b4;
- nd->mTransformation.c4 = snode->mTargetPosition.z - snode->mTransform.c4;
-
- nd->mParent = node;
-
- // The .Target node is always the first child node
- for (unsigned int m = 0; m < node->mNumChildren;++m)
- node->mChildren[m+1] = node->mChildren[m];
-
- node->mChildren[0] = nd;
- node->mNumChildren++;
-
- // What we did is so great, it is at least worth a debug message
- DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")");
- }
- }
-
- // Allocate enough space for the child nodes
- // We allocate one slot more in case this is a target camera/light
- pcParent->mNumChildren = (unsigned int)apcNodes.size();
- if (pcParent->mNumChildren) {
- pcParent->mChildren = new aiNode*[apcNodes.size()+1 /* PLUS ONE !!! */];
-
- // now build all nodes for our nice new children
- for (unsigned int p = 0; p < apcNodes.size();++p)
- pcParent->mChildren[p] = apcNodes[p];
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build the output node graph
-void ASEImporter::BuildNodes(std::vector<BaseNode*>& nodes) {
- ai_assert(NULL != pcScene);
-
- // allocate the one and only root node
- aiNode* root = pcScene->mRootNode = new aiNode();
- root->mName.Set("<ASERoot>");
-
- // Setup the coordinate system transformation
- pcScene->mRootNode->mNumChildren = 1;
- pcScene->mRootNode->mChildren = new aiNode*[1];
- aiNode* ch = pcScene->mRootNode->mChildren[0] = new aiNode();
- ch->mParent = root;
-
- // Change the transformation matrix of all nodes
- for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it) {
- aiMatrix4x4& m = (*it)->mTransform;
- m.Transpose(); // row-order vs column-order
- }
-
- // add all nodes
- AddNodes(nodes,ch,NULL);
-
- // now iterate through al nodes and find those that have not yet
- // been added to the nodegraph (= their parent could not be recognized)
- std::vector<const BaseNode*> aiList;
- for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it) {
- if ((*it)->mProcessed) {
- continue;
- }
-
- // check whether our parent is known
- bool bKnowParent = false;
-
- // search the list another time, starting *here* and try to find out whether
- // there is a node that references *us* as a parent
- for (std::vector<BaseNode*>::const_iterator it2 = nodes.begin();it2 != end; ++it2) {
- if (it2 == it) {
- continue;
- }
-
- if ((*it2)->mName == (*it)->mParent) {
- bKnowParent = true;
- break;
- }
- }
- if (!bKnowParent) {
- aiList.push_back(*it);
- }
- }
-
- // Are there ane orphaned nodes?
- if (!aiList.empty()) {
- std::vector<aiNode*> apcNodes;
- apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren);
-
- for (unsigned int i = 0; i < pcScene->mRootNode->mNumChildren;++i)
- apcNodes.push_back(pcScene->mRootNode->mChildren[i]);
-
- delete[] pcScene->mRootNode->mChildren;
- for (std::vector<const BaseNode*>::/*const_*/iterator i = aiList.begin();i != aiList.end();++i) {
- const ASE::BaseNode* src = *i;
-
- // The parent is not known, so we can assume that we must add
- // this node to the root node of the whole scene
- aiNode* pcNode = new aiNode();
- pcNode->mParent = pcScene->mRootNode;
- pcNode->mName.Set(src->mName);
- AddMeshes(src,pcNode);
- AddNodes(nodes,pcNode,pcNode->mName.data);
- apcNodes.push_back(pcNode);
- }
-
- // Regenerate our output array
- pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
- for (unsigned int i = 0; i < apcNodes.size();++i)
- pcScene->mRootNode->mChildren[i] = apcNodes[i];
-
- pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size();
- }
-
- // Reset the third color set to NULL - we used this field to store a temporary pointer
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
- pcScene->mMeshes[i]->mColors[2] = NULL;
-
- // The root node should not have at least one child or the file is valid
- if (!pcScene->mRootNode->mNumChildren) {
- throw DeadlyImportError("ASE: No nodes loaded. The file is either empty or corrupt");
- }
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pcScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert the imported data to the internal verbose representation
-void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) {
- // allocate output storage
- std::vector<aiVector3D> mPositions;
- std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- std::vector<aiColor4D> mVertexColors;
- std::vector<aiVector3D> mNormals;
- std::vector<BoneVertex> mBoneVertices;
-
- unsigned int iSize = (unsigned int)mesh.mFaces.size() * 3;
- mPositions.resize(iSize);
-
- // optional texture coordinates
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) {
- if (!mesh.amTexCoords[i].empty()) {
- amTexCoords[i].resize(iSize);
- }
- }
- // optional vertex colors
- if (!mesh.mVertexColors.empty()) {
- mVertexColors.resize(iSize);
- }
-
- // optional vertex normals (vertex normals can simply be copied)
- if (!mesh.mNormals.empty()) {
- mNormals.resize(iSize);
- }
- // bone vertices. There is no need to change the bone list
- if (!mesh.mBoneVertices.empty()) {
- mBoneVertices.resize(iSize);
- }
-
- // iterate through all faces in the mesh
- unsigned int iCurrent = 0, fi = 0;
- for (std::vector<ASE::Face>::iterator i = mesh.mFaces.begin();i != mesh.mFaces.end();++i,++fi) {
- for (unsigned int n = 0; n < 3;++n,++iCurrent)
- {
- mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
-
- // add texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (mesh.amTexCoords[c].empty())break;
- amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
- }
- // add vertex colors
- if (!mesh.mVertexColors.empty()) {
- mVertexColors[iCurrent] = mesh.mVertexColors[(*i).mColorIndices[n]];
- }
- // add normal vectors
- if (!mesh.mNormals.empty()) {
- mNormals[iCurrent] = mesh.mNormals[fi*3+n];
- mNormals[iCurrent].Normalize();
- }
-
- // handle bone vertices
- if ((*i).mIndices[n] < mesh.mBoneVertices.size()) {
- // (sometimes this will cause bone verts to be duplicated
- // however, I' quite sure Schrompf' JoinVerticesStep
- // will fix that again ...)
- mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]];
- }
- (*i).mIndices[n] = iCurrent;
- }
- }
-
- // replace the old arrays
- mesh.mNormals = mNormals;
- mesh.mPositions = mPositions;
- mesh.mVertexColors = mVertexColors;
-
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- mesh.amTexCoords[c] = amTexCoords[c];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy a texture from the ASE structs to the output material
-void CopyASETexture(MaterialHelper& mat, ASE::Texture& texture, aiTextureType type)
-{
- // Setup the texture name
- aiString tex;
- tex.Set( texture.mMapName);
- mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
-
- // Setup the texture blend factor
- if (is_not_qnan(texture.mTextureBlend))
- mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
-
- // Setup texture UV transformations
- mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert from ASE material to output material
-void ASEImporter::ConvertMaterial(ASE::Material& mat)
-{
- // LARGE TODO: Much code her is copied from 3DS ... join them maybe?
-
- // Allocate the output material
- mat.pcInstance = new MaterialHelper();
-
- // At first add the base ambient color of the
- // scene to the material
- mat.mAmbient.r += mParser->m_clrAmbient.r;
- mat.mAmbient.g += mParser->m_clrAmbient.g;
- mat.mAmbient.b += mParser->m_clrAmbient.b;
-
- aiString name;
- name.Set( mat.mName);
- mat.pcInstance->AddProperty( &name, AI_MATKEY_NAME);
-
- // material colors
- mat.pcInstance->AddProperty( &mat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat.pcInstance->AddProperty( &mat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.pcInstance->AddProperty( &mat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat.pcInstance->AddProperty( &mat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // shininess
- if (0.0f != mat.mSpecularExponent && 0.0f != mat.mShininessStrength)
- {
- mat.pcInstance->AddProperty( &mat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
- mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
- }
- // If there is no shininess, we can disable phong lighting
- else if (D3DS::Discreet3DS::Metal == mat.mShading ||
- D3DS::Discreet3DS::Phong == mat.mShading ||
- D3DS::Discreet3DS::Blinn == mat.mShading)
- {
- mat.mShading = D3DS::Discreet3DS::Gouraud;
- }
-
- // opacity
- mat.pcInstance->AddProperty<float>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
-
- // Two sided rendering?
- if (mat.mTwoSided)
- {
- int i = 1;
- mat.pcInstance->AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
- }
-
- // shading mode
- aiShadingMode eShading = aiShadingMode_NoShading;
- switch (mat.mShading)
- {
- case D3DS::Discreet3DS::Flat:
- eShading = aiShadingMode_Flat; break;
- case D3DS::Discreet3DS::Phong :
- eShading = aiShadingMode_Phong; break;
- case D3DS::Discreet3DS::Blinn :
- eShading = aiShadingMode_Blinn; break;
-
- // I don't know what "Wire" shading should be,
- // assume it is simple lambertian diffuse (L dot N) shading
- case D3DS::Discreet3DS::Wire:
- {
- // set the wireframe flag
- unsigned int iWire = 1;
- mat.pcInstance->AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
- case D3DS::Discreet3DS::Gouraud:
- eShading = aiShadingMode_Gouraud; break;
- case D3DS::Discreet3DS::Metal :
- eShading = aiShadingMode_CookTorrance; break;
- }
- mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
-
- // DIFFUSE texture
- if ( mat.sTexDiffuse.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexDiffuse, aiTextureType_DIFFUSE);
-
- // SPECULAR texture
- if ( mat.sTexSpecular.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexSpecular, aiTextureType_SPECULAR);
-
- // AMBIENT texture
- if ( mat.sTexAmbient.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexAmbient, aiTextureType_AMBIENT);
-
- // OPACITY texture
- if ( mat.sTexOpacity.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexOpacity, aiTextureType_OPACITY);
-
- // EMISSIVE texture
- if ( mat.sTexEmissive.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexEmissive, aiTextureType_EMISSIVE);
-
- // BUMP texture
- if ( mat.sTexBump.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexBump, aiTextureType_HEIGHT);
-
- // SHININESS texture
- if ( mat.sTexShininess.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexShininess, aiTextureType_SHININESS);
-
- // store the name of the material itself, too
- if ( mat.mName.length() > 0) {
- aiString tex;tex.Set( mat.mName);
- mat.pcInstance->AddProperty( &tex, AI_MATKEY_NAME);
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output meshes
-void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMeshes)
-{
- // validate the material index of the mesh
- if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) {
- mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1;
- DefaultLogger::get()->warn("Material index is out of range");
- }
-
- // If the material the mesh is assigned to is consisting of submeshes, split it
- if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
- std::vector<ASE::Material> vSubMaterials = mParser->
- m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
-
- std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[vSubMaterials.size()];
-
- // build a list of all faces per submaterial
- for (unsigned int i = 0; i < mesh.mFaces.size();++i) {
- // check range
- if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) {
- DefaultLogger::get()->warn("Submaterial index is out of range");
-
- // use the last material instead
- aiSplit[vSubMaterials.size()-1].push_back(i);
- }
- else aiSplit[mesh.mFaces[i].iMaterial].push_back(i);
- }
-
- // now generate submeshes
- for (unsigned int p = 0; p < vSubMaterials.size();++p) {
- if (!aiSplit[p].empty()) {
-
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // let the sub material index
- p_pcOut->mMaterialIndex = p;
-
- // we will need this material
- mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials[p].bNeed = true;
-
- // store the real index here ... color channel 3
- p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
-
- // store a pointer to the mesh in color channel 2
- p_pcOut->mColors[2] = (aiColor4D*) &mesh;
- avOutMeshes.push_back(p_pcOut);
-
- // convert vertices
- p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3;
- p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
-
- // receive output vertex weights
- std::vector<std::pair<unsigned int, float> > *avOutputBones = NULL;
- if (!mesh.mBones.empty()) {
- avOutputBones = new std::vector<std::pair<unsigned int, float> >[mesh.mBones.size()];
- }
-
- // allocate enough storage for faces
- p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
-
- unsigned int iBase = 0,iIndex;
- if (p_pcOut->mNumVertices) {
- p_pcOut->mVertices = new aiVector3D[p_pcOut->mNumVertices];
- p_pcOut->mNormals = new aiVector3D[p_pcOut->mNumVertices];
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
-
- iIndex = aiSplit[p][q];
-
- p_pcOut->mFaces[q].mIndices = new unsigned int[3];
- p_pcOut->mFaces[q].mNumIndices = 3;
-
- for (unsigned int t = 0; t < 3;++t, ++iBase) {
- const uint32_t iIndex2 = mesh.mFaces[iIndex].mIndices[t];
-
- p_pcOut->mVertices[iBase] = mesh.mPositions [iIndex2];
- p_pcOut->mNormals [iBase] = mesh.mNormals [iIndex2];
-
- // convert bones, if existing
- if (!mesh.mBones.empty()) {
- // check whether there is a vertex weight for this vertex index
- if (iIndex2 < mesh.mBoneVertices.size()) {
-
- for (std::vector<std::pair<int,float> >::const_iterator
- blubb = mesh.mBoneVertices[iIndex2].mBoneWeights.begin();
- blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end();++blubb) {
-
- // NOTE: illegal cases have already been filtered out
- avOutputBones[(*blubb).first].push_back(std::pair<unsigned int, float>(
- iBase,(*blubb).second));
- }
- }
- }
- p_pcOut->mFaces[q].mIndices[t] = iBase;
- }
- }
- }
- // convert texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS sets supported)
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (!mesh.amTexCoords[c].empty())
- {
- p_pcOut->mTextureCoords[c] = new aiVector3D[p_pcOut->mNumVertices];
- iBase = 0;
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
- iIndex = aiSplit[p][q];
- for (unsigned int t = 0; t < 3;++t) {
- p_pcOut->mTextureCoords[c][iBase++] = mesh.amTexCoords[c][mesh.mFaces[iIndex].mIndices[t]];
- }
- }
- // Setup the number of valid vertex components
- p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
- }
- }
-
- // Convert vertex colors (only one set supported)
- if (!mesh.mVertexColors.empty()){
- p_pcOut->mColors[0] = new aiColor4D[p_pcOut->mNumVertices];
- iBase = 0;
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
- iIndex = aiSplit[p][q];
- for (unsigned int t = 0; t < 3;++t) {
- p_pcOut->mColors[0][iBase++] = mesh.mVertexColors[mesh.mFaces[iIndex].mIndices[t]];
- }
- }
- }
- // Copy bones
- if (!mesh.mBones.empty()) {
- p_pcOut->mNumBones = 0;
- for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
- if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++;
-
- p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ];
- aiBone** pcBone = p_pcOut->mBones;
- for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
- {
- if (!avOutputBones[mrspock].empty()) {
- // we will need this bone. add it to the output mesh and
- // add all per-vertex weights
- aiBone* pc = *pcBone = new aiBone();
- pc->mName.Set(mesh.mBones[mrspock].mName);
-
- pc->mNumWeights = (unsigned int)avOutputBones[mrspock].size();
- pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk)
- {
- const std::pair<unsigned int,float>& ref = avOutputBones[mrspock][captainkirk];
- pc->mWeights[captainkirk].mVertexId = ref.first;
- pc->mWeights[captainkirk].mWeight = ref.second;
- }
- ++pcBone;
- }
- }
- // delete allocated storage
- delete[] avOutputBones;
- }
- }
- }
- // delete storage
- delete[] aiSplit;
- }
- else
- {
- // Otherwise we can simply copy the data to one output mesh
- // This codepath needs less memory and uses fast memcpy()s
- // to do the actual copying. So I think it is worth the
- // effort here.
-
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // set an empty sub material index
- p_pcOut->mMaterialIndex = ASE::Face::DEFAULT_MATINDEX;
- mParser->m_vMaterials[mesh.iMaterialIndex].bNeed = true;
-
- // store the real index here ... in color channel 3
- p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
-
- // store a pointer to the mesh in color channel 2
- p_pcOut->mColors[2] = (aiColor4D*) &mesh;
- avOutMeshes.push_back(p_pcOut);
-
- // If the mesh hasn't faces or vertices, there are two cases
- // possible: 1. the model is invalid. 2. This is a dummy
- // helper object which we are going to remove later ...
- if (mesh.mFaces.empty() || mesh.mPositions.empty()) {
- return;
- }
-
- // convert vertices
- p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
- p_pcOut->mNumFaces = (unsigned int)mesh.mFaces.size();
-
- // allocate enough storage for faces
- p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
-
- // copy vertices
- p_pcOut->mVertices = new aiVector3D[mesh.mPositions.size()];
- memcpy(p_pcOut->mVertices,&mesh.mPositions[0],
- mesh.mPositions.size() * sizeof(aiVector3D));
-
- // copy normals
- p_pcOut->mNormals = new aiVector3D[mesh.mNormals.size()];
- memcpy(p_pcOut->mNormals,&mesh.mNormals[0],
- mesh.mNormals.size() * sizeof(aiVector3D));
-
- // copy texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (!mesh.amTexCoords[c].empty()) {
- p_pcOut->mTextureCoords[c] = new aiVector3D[mesh.amTexCoords[c].size()];
- memcpy(p_pcOut->mTextureCoords[c],&mesh.amTexCoords[c][0],
- mesh.amTexCoords[c].size() * sizeof(aiVector3D));
-
- // setup the number of valid vertex components
- p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
- }
- }
-
- // copy vertex colors
- if (!mesh.mVertexColors.empty()) {
- p_pcOut->mColors[0] = new aiColor4D[mesh.mVertexColors.size()];
- memcpy(p_pcOut->mColors[0],&mesh.mVertexColors[0],
- mesh.mVertexColors.size() * sizeof(aiColor4D));
- }
-
- // copy faces
- for (unsigned int iFace = 0; iFace < p_pcOut->mNumFaces;++iFace) {
- p_pcOut->mFaces[iFace].mNumIndices = 3;
- p_pcOut->mFaces[iFace].mIndices = new unsigned int[3];
-
- // copy indices
- p_pcOut->mFaces[iFace].mIndices[0] = mesh.mFaces[iFace].mIndices[0];
- p_pcOut->mFaces[iFace].mIndices[1] = mesh.mFaces[iFace].mIndices[1];
- p_pcOut->mFaces[iFace].mIndices[2] = mesh.mFaces[iFace].mIndices[2];
- }
-
- // copy vertex bones
- if (!mesh.mBones.empty() && !mesh.mBoneVertices.empty()) {
- std::vector<aiVertexWeight>* avBonesOut = new std::vector<aiVertexWeight>[mesh.mBones.size()];
-
- // find all vertex weights for this bone
- unsigned int quak = 0;
- for (std::vector<BoneVertex>::const_iterator harrypotter = mesh.mBoneVertices.begin();
- harrypotter != mesh.mBoneVertices.end();++harrypotter,++quak) {
-
- for (std::vector<std::pair<int,float> >::const_iterator
- ronaldweasley = (*harrypotter).mBoneWeights.begin();
- ronaldweasley != (*harrypotter).mBoneWeights.end();++ronaldweasley)
- {
- aiVertexWeight weight;
- weight.mVertexId = quak;
- weight.mWeight = (*ronaldweasley).second;
- avBonesOut[(*ronaldweasley).first].push_back(weight);
- }
- }
-
- // now build a final bone list
- p_pcOut->mNumBones = 0;
- for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy)
- if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++;
-
- p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones];
- aiBone** pcBone = p_pcOut->mBones;
- for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy) {
- if (!avBonesOut[jfkennedy].empty()) {
- aiBone* pc = *pcBone = new aiBone();
- pc->mName.Set(mesh.mBones[jfkennedy].mName);
- pc->mNumWeights = (unsigned int)avBonesOut[jfkennedy].size();
- pc->mWeights = new aiVertexWeight[pc->mNumWeights];
- ::memcpy(pc->mWeights,&avBonesOut[jfkennedy][0],
- sizeof(aiVertexWeight) * pc->mNumWeights);
- ++pcBone;
- }
- }
-
- // delete allocated storage
- delete[] avBonesOut;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup proper material indices and build output materials
-void ASEImporter::BuildMaterialIndices()
-{
- ai_assert(NULL != pcScene);
-
- // iterate through all materials and check whether we need them
- for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)
- {
- ASE::Material& mat = mParser->m_vMaterials[iMat];
- if (mat.bNeed) {
- // Convert it to the aiMaterial layout
- ConvertMaterial(mat);
- ++pcScene->mNumMaterials;
- }
- for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)
- {
- ASE::Material& submat = mat.avSubMaterials[iSubMat];
- if (submat.bNeed) {
- // Convert it to the aiMaterial layout
- ConvertMaterial(submat);
- ++pcScene->mNumMaterials;
- }
- }
- }
-
- // allocate the output material array
- pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials];
- D3DS::Material** pcIntMaterials = new D3DS::Material*[pcScene->mNumMaterials];
-
- unsigned int iNum = 0;
- for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) {
- ASE::Material& mat = mParser->m_vMaterials[iMat];
- if (mat.bNeed)
- {
- ai_assert(NULL != mat.pcInstance);
- pcScene->mMaterials[iNum] = mat.pcInstance;
-
- // Store the internal material, too
- pcIntMaterials[iNum] = &mat;
-
- // Iterate through all meshes and search for one which is using
- // this top-level material index
- for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)
- {
- aiMesh* mesh = pcScene->mMeshes[iMesh];
- if (ASE::Face::DEFAULT_MATINDEX == mesh->mMaterialIndex &&
- iMat == (uintptr_t)mesh->mColors[3])
- {
- mesh->mMaterialIndex = iNum;
- mesh->mColors[3] = NULL;
- }
- }
- iNum++;
- }
- for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat) {
- ASE::Material& submat = mat.avSubMaterials[iSubMat];
- if (submat.bNeed) {
- ai_assert(NULL != submat.pcInstance);
- pcScene->mMaterials[iNum] = submat.pcInstance;
-
- // Store the internal material, too
- pcIntMaterials[iNum] = &submat;
-
- // Iterate through all meshes and search for one which is using
- // this sub-level material index
- for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh) {
- aiMesh* mesh = pcScene->mMeshes[iMesh];
-
- if (iSubMat == mesh->mMaterialIndex && iMat == (uintptr_t)mesh->mColors[3]) {
- mesh->mMaterialIndex = iNum;
- mesh->mColors[3] = NULL;
- }
- }
- iNum++;
- }
- }
- }
-
- // Dekete our temporary array
- delete[] pcIntMaterials;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate normal vectors basing on smoothing groups
-bool ASEImporter::GenerateNormals(ASE::Mesh& mesh) {
-
- if (!mesh.mNormals.empty() && !configRecomputeNormals)
- {
- // Check whether there are only uninitialized normals. If there are
- // some, skip all normals from the file and compute them on our own
- for (std::vector<aiVector3D>::const_iterator qq = mesh.mNormals.begin();qq != mesh.mNormals.end();++qq) {
- if ((*qq).x || (*qq).y || (*qq).z)
- {
- return true;
- }
- }
- }
- // The array is reused.
- ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
- return false;
-}
-
-#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
diff --git a/3rdparty/assimp/code/ASELoader.h b/3rdparty/assimp/code/ASELoader.h
deleted file mode 100644
index 884e7df8..00000000
--- a/3rdparty/assimp/code/ASELoader.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file ASELoader.h
- * @brief Definition of the .ASE importer class.
- */
-#ifndef AI_ASELOADER_H_INCLUDED
-#define AI_ASELOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-struct aiNode;
-#include "ASEParser.h"
-
-namespace Assimp {
-class MaterialHelper;
-
-// --------------------------------------------------------------------------------
-/** Importer class for the 3DS ASE ASCII format.
- *
- */
-class ASEImporter : public BaseImporter {
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- ASEImporter();
-
- /** Destructor, private as well */
- ~ASEImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-
-private:
-
- // -------------------------------------------------------------------
- /** Generate normal vectors basing on smoothing groups
- * (in some cases the normal are already contained in the file)
- * \param mesh Mesh to work on
- * \return false if the normals have been recomputed
- */
- bool GenerateNormals(ASE::Mesh& mesh);
-
-
- // -------------------------------------------------------------------
- /** Create valid vertex/normal/UV/color/face lists.
- * All elements are unique, faces have only one set of indices
- * after this step occurs.
- * \param mesh Mesh to work on
- */
- void BuildUniqueRepresentation(ASE::Mesh& mesh);
-
-
- /** Create one-material-per-mesh meshes ;-)
- * \param mesh Mesh to work with
- * \param Receives the list of all created meshes
- */
- void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
-
-
- // -------------------------------------------------------------------
- /** Convert a material to a MaterialHelper object
- * \param mat Input material
- */
- void ConvertMaterial(ASE::Material& mat);
-
-
- // -------------------------------------------------------------------
- /** Setup the final material indices for each mesh
- */
- void BuildMaterialIndices();
-
-
- // -------------------------------------------------------------------
- /** Build the node graph
- */
- void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
-
-
- // -------------------------------------------------------------------
- /** Build output cameras
- */
- void BuildCameras();
-
-
- // -------------------------------------------------------------------
- /** Build output lights
- */
- void BuildLights();
-
-
- // -------------------------------------------------------------------
- /** Build output animations
- */
- void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
-
-
- // -------------------------------------------------------------------
- /** Add sub nodes to a node
- * \param pcParent parent node to be filled
- * \param szName Name of the parent node
- * \param matrix Current transform
- */
- void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
- aiNode* pcParent,const char* szName);
-
- void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
- aiNode* pcParent,const char* szName,
- const aiMatrix4x4& matrix);
-
- void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
-
- // -------------------------------------------------------------------
- /** Generate a default material and add it to the parser's list
- * Called if no material has been found in the file (rare for ASE,
- * but not impossible)
- */
- void GenerateDefaultMaterial();
-
-protected:
-
- /** Parser instance */
- ASE::Parser* mParser;
-
- /** Buffer to hold the loaded file */
- char* mBuffer;
-
- /** Scene to be filled */
- aiScene* pcScene;
-
- /** Config options: Recompute the normals in every case - WA
- for 3DS Max broken ASE normal export */
- bool configRecomputeNormals;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/ASEParser.cpp b/3rdparty/assimp/code/ASEParser.cpp
deleted file mode 100644
index 0b3584a2..00000000
--- a/3rdparty/assimp/code/ASEParser.cpp
+++ /dev/null
@@ -1,2150 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file ASEParser.cpp
- * @brief Implementation of the ASE parser class
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "TextureTransform.h"
-#include "ASELoader.h"
-#include "MaterialSystem.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace Assimp::ASE;
-
-
-// ------------------------------------------------------------------------------------------------
-// Begin an ASE parsing function
-
-#define AI_ASE_PARSER_INIT() \
- int iDepth = 0;
-
-// ------------------------------------------------------------------------------------------------
-// Handle a "top-level" section in the file. EOF is no error in this case.
-
-#define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \
- else if ('{' == *filePtr)iDepth++; \
- else if ('}' == *filePtr) \
- { \
- if (0 == --iDepth) \
- { \
- ++filePtr; \
- SkipToNextToken(); \
- return; \
- } \
- } \
- else if ('\0' == *filePtr) \
- { \
- return; \
- } \
- if (IsLineEnd(*filePtr) && !bLastWasEndLine) \
- { \
- ++iLineNumber; \
- bLastWasEndLine = true; \
- } else bLastWasEndLine = false; \
- ++filePtr;
-
-// ------------------------------------------------------------------------------------------------
-// Handle a nested section in the file. EOF is an error in this case
-// @param level "Depth" of the section
-// @param msg Full name of the section (including the asterisk)
-
-#define AI_ASE_HANDLE_SECTION(level, msg) \
- if ('{' == *filePtr)iDepth++; \
- else if ('}' == *filePtr) \
- { \
- if (0 == --iDepth) \
- { \
- ++filePtr; \
- SkipToNextToken(); \
- return; \
- } \
- } \
- else if ('\0' == *filePtr) \
- { \
- LogError("Encountered unexpected EOL while parsing a " msg \
- " chunk (Level " level ")"); \
- } \
- if (IsLineEnd(*filePtr) && !bLastWasEndLine) \
- { \
- ++iLineNumber; \
- bLastWasEndLine = true; \
- } else bLastWasEndLine = false; \
- ++filePtr;
-
-// ------------------------------------------------------------------------------------------------
-Parser::Parser (const char* szFile, unsigned int fileFormatDefault)
-{
- ai_assert(NULL != szFile);
- filePtr = szFile;
- iFileFormat = fileFormatDefault;
-
- // make sure that the color values are invalid
- m_clrBackground.r = get_qnan();
- m_clrAmbient.r = get_qnan();
-
- // setup some default values
- iLineNumber = 0;
- iFirstFrame = 0;
- iLastFrame = 0;
- iFrameSpeed = 30; // use 30 as default value for this property
- iTicksPerFrame = 1; // use 1 as default value for this property
- bLastWasEndLine = false; // need to handle \r\n seqs due to binary file mapping
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::LogWarning(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
-#else
- snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
-#endif
-
- // output the warning to the logger ...
- DefaultLogger::get()->warn(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::LogInfo(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
-#else
- snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
-#endif
-
- // output the information to the logger ...
- DefaultLogger::get()->info(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::LogError(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
-#else
- snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
-#endif
-
- // throw an exception
- throw DeadlyImportError(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::SkipToNextToken()
-{
- while (true)
- {
- char me = *filePtr;
-
- // increase the line number counter if necessary
- if (IsLineEnd(me) && !bLastWasEndLine)
- {
- ++iLineNumber;
- bLastWasEndLine = true;
- }
- else bLastWasEndLine = false;
- if ('*' == me || '}' == me || '{' == me)return true;
- if ('\0' == me)return false;
-
- ++filePtr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::SkipSection()
-{
- // must handle subsections ...
- int iCnt = 0;
- while (true)
- {
- if ('}' == *filePtr)
- {
- --iCnt;
- if (0 == iCnt)
- {
- // go to the next valid token ...
- ++filePtr;
- SkipToNextToken();
- return true;
- }
- }
- else if ('{' == *filePtr)
- {
- ++iCnt;
- }
- else if ('\0' == *filePtr)
- {
- LogWarning("Unable to parse block: Unexpected EOF, closing bracket \'}\' was expected [#1]");
- return false;
- }
- else if (IsLineEnd(*filePtr))++iLineNumber;
- ++filePtr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::Parse()
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Version should be 200. Validate this ...
- if (TokenMatch(filePtr,"3DSMAX_ASCIIEXPORT",18))
- {
- unsigned int fmt;
- ParseLV4MeshLong(fmt);
-
- if (fmt > 200)
- {
- LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
- be <= 200");
- }
- // *************************************************************
- // - fmt will be 0 if we're unable to read the version number
- // there are some faulty files without a version number ...
- // in this case we'll guess the exact file format by looking
- // at the file extension (ASE, ASK, ASC)
- // *************************************************************
-
- if (fmt)iFileFormat = fmt;
- continue;
- }
- // main scene information
- if (TokenMatch(filePtr,"SCENE",5))
- {
- ParseLV1SceneBlock();
- continue;
- }
- // "group" - no implementation yet, in facte
- // we're just ignoring them for the moment
- if (TokenMatch(filePtr,"GROUP",5))
- {
- Parse();
- continue;
- }
- // material list
- if (TokenMatch(filePtr,"MATERIAL_LIST",13))
- {
- ParseLV1MaterialListBlock();
- continue;
- }
- // geometric object (mesh)
- if (TokenMatch(filePtr,"GEOMOBJECT",10))
-
- {
- m_vMeshes.push_back(Mesh());
- ParseLV1ObjectBlock(m_vMeshes.back());
- continue;
- }
- // helper object = dummy in the hierarchy
- if (TokenMatch(filePtr,"HELPEROBJECT",12))
-
- {
- m_vDummies.push_back(Dummy());
- ParseLV1ObjectBlock(m_vDummies.back());
- continue;
- }
- // light object
- if (TokenMatch(filePtr,"LIGHTOBJECT",11))
-
- {
- m_vLights.push_back(Light());
- ParseLV1ObjectBlock(m_vLights.back());
- continue;
- }
- // camera object
- if (TokenMatch(filePtr,"CAMERAOBJECT",12))
- {
- m_vCameras.push_back(Camera());
- ParseLV1ObjectBlock(m_vCameras.back());
- continue;
- }
- // comment - print it on the console
- if (TokenMatch(filePtr,"COMMENT",7))
- {
- std::string out = "<unknown>";
- ParseString(out,"*COMMENT");
- LogInfo(("Comment: " + out).c_str());
- continue;
- }
- // ASC bone weights
- if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr,"MESH_SOFTSKINVERTS",18))
- {
- ParseLV1SoftSkinBlock();
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1SoftSkinBlock()
-{
- // TODO: fix line counting here
-
- // **************************************************************
- // The soft skin block is formatted differently. There are no
- // nested sections supported and the single elements aren't
- // marked by keywords starting with an asterisk.
-
- /**
- FORMAT BEGIN
-
- *MESH_SOFTSKINVERTS {
- <nodename>
- <number of vertices>
-
- [for <number of vertices> times:]
- <number of weights> [for <number of weights> times:] <bone name> <weight>
- }
-
- FORMAT END
- */
- // **************************************************************
- while (true)
- {
- if (*filePtr == '}' ) {++filePtr;return;}
- else if (*filePtr == '\0') return;
- else if (*filePtr == '{' ) ++filePtr;
-
- else // if (!IsSpace(*filePtr) && !IsLineEnd(*filePtr))
- {
- ASE::Mesh* curMesh = NULL;
- unsigned int numVerts = 0;
-
- const char* sz = filePtr;
- while (!IsSpaceOrNewLine(*filePtr))++filePtr;
-
- const unsigned int diff = (unsigned int)(filePtr-sz);
- if (diff)
- {
- std::string name = std::string(sz,diff);
- for (std::vector<ASE::Mesh>::iterator it = m_vMeshes.begin();
- it != m_vMeshes.end(); ++it)
- {
- if ((*it).mName == name)
- {
- curMesh = & (*it);
- break;
- }
- }
- if (!curMesh)
- {
- LogWarning("Encountered unknown mesh in *MESH_SOFTSKINVERTS section");
-
- // Skip the mesh data - until we find a new mesh
- // or the end of the *MESH_SOFTSKINVERTS section
- while (true)
- {
- SkipSpacesAndLineEnd(&filePtr);
- if (*filePtr == '}')
- {++filePtr;return;}
- else if (!IsNumeric(*filePtr))
- break;
-
- SkipLine(&filePtr);
- }
- }
- else
- {
- SkipSpacesAndLineEnd(&filePtr);
- ParseLV4MeshLong(numVerts);
-
- // Reserve enough storage
- curMesh->mBoneVertices.reserve(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- SkipSpacesAndLineEnd(&filePtr);
- unsigned int numWeights;
- ParseLV4MeshLong(numWeights);
-
- curMesh->mBoneVertices.push_back(ASE::BoneVertex());
- ASE::BoneVertex& vert = curMesh->mBoneVertices.back();
-
- // Reserve enough storage
- vert.mBoneWeights.reserve(numWeights);
-
- for (unsigned int w = 0; w < numWeights;++w)
- {
- std::string bone;
- ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
-
- // Find the bone in the mesh's list
- std::pair<int,float> me;
- me.first = -1;
-
- for (unsigned int n = 0; n < curMesh->mBones.size();++n)
- {
- if (curMesh->mBones[n].mName == bone)
- {
- me.first = n;
- break;
- }
- }
- if (-1 == me.first)
- {
- // We don't have this bone yet, so add it to the list
- me.first = (int)curMesh->mBones.size();
- curMesh->mBones.push_back(ASE::Bone(bone));
- }
- ParseLV4MeshFloat( me.second );
-
- // Add the new bone weight to list
- vert.mBoneWeights.push_back(me);
- }
- }
- }
- }
- }
- ++filePtr;
- SkipSpacesAndLineEnd(&filePtr);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1SceneBlock()
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"SCENE_BACKGROUND_STATIC",23))
-
- {
- // parse a color triple and assume it is really the bg color
- ParseLV4MeshFloatTriple( &m_clrBackground.r );
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_AMBIENT_STATIC",20))
-
- {
- // parse a color triple and assume it is really the bg color
- ParseLV4MeshFloatTriple( &m_clrAmbient.r );
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_FIRSTFRAME",16))
- {
- ParseLV4MeshLong(iFirstFrame);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_LASTFRAME",15))
- {
- ParseLV4MeshLong(iLastFrame);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_FRAMESPEED",16))
- {
- ParseLV4MeshLong(iFrameSpeed);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_TICKSPERFRAME",19))
- {
- ParseLV4MeshLong(iTicksPerFrame);
- continue;
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1MaterialListBlock()
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iMaterialCount = 0;
- unsigned int iOldMaterialCount = (unsigned int)m_vMaterials.size();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"MATERIAL_COUNT",14))
- {
- ParseLV4MeshLong(iMaterialCount);
-
- // now allocate enough storage to hold all materials
- m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
- continue;
- }
- if (TokenMatch(filePtr,"MATERIAL",8))
- {
- unsigned int iIndex = 0;
- ParseLV4MeshLong(iIndex);
-
- if (iIndex >= iMaterialCount)
- {
- LogWarning("Out of range: material index is too large");
- iIndex = iMaterialCount-1;
- }
-
- // get a reference to the material
- Material& sMat = m_vMaterials[iIndex+iOldMaterialCount];
- // parse the material block
- ParseLV2MaterialBlock(sMat);
- continue;
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumSubMaterials = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"MATERIAL_NAME",13))
- {
- if (!ParseString(mat.mName,"*MATERIAL_NAME"))
- SkipToNextToken();
- continue;
- }
- // ambient material color
- if (TokenMatch(filePtr,"MATERIAL_AMBIENT",16))
- {
- ParseLV4MeshFloatTriple(&mat.mAmbient.r);
- continue;
- }
- // diffuse material color
- if (TokenMatch(filePtr,"MATERIAL_DIFFUSE",16) )
- {
- ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
- continue;
- }
- // specular material color
- if (TokenMatch(filePtr,"MATERIAL_SPECULAR",17))
- {
- ParseLV4MeshFloatTriple(&mat.mSpecular.r);
- continue;
- }
- // material shading type
- if (TokenMatch(filePtr,"MATERIAL_SHADING",16))
- {
- if (TokenMatch(filePtr,"Blinn",5))
- {
- mat.mShading = Discreet3DS::Blinn;
- }
- else if (TokenMatch(filePtr,"Phong",5))
- {
- mat.mShading = Discreet3DS::Phong;
- }
- else if (TokenMatch(filePtr,"Flat",4))
- {
- mat.mShading = Discreet3DS::Flat;
- }
- else if (TokenMatch(filePtr,"Wire",4))
- {
- mat.mShading = Discreet3DS::Wire;
- }
- else
- {
- // assume gouraud shading
- mat.mShading = Discreet3DS::Gouraud;
- SkipToNextToken();
- }
- continue;
- }
- // material transparency
- if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
- {
- ParseLV4MeshFloat(mat.mTransparency);
- mat.mTransparency = 1.0f - mat.mTransparency;continue;
- }
- // material self illumination
- if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
- {
- float f = 0.0f;
- ParseLV4MeshFloat(f);
-
- mat.mEmissive.r = f;
- mat.mEmissive.g = f;
- mat.mEmissive.b = f;
- continue;
- }
- // material shininess
- if (TokenMatch(filePtr,"MATERIAL_SHINE",14) )
- {
- ParseLV4MeshFloat(mat.mSpecularExponent);
- mat.mSpecularExponent *= 15;
- continue;
- }
- // two-sided material
- if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) )
- {
- mat.mTwoSided = true;
- continue;
- }
- // material shininess strength
- if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22))
- {
- ParseLV4MeshFloat(mat.mShininessStrength);
- continue;
- }
- // diffuse color map
- if (TokenMatch(filePtr,"MAP_DIFFUSE",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexDiffuse);
- continue;
- }
- // ambient color map
- if (TokenMatch(filePtr,"MAP_AMBIENT",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexAmbient);
- continue;
- }
- // specular color map
- if (TokenMatch(filePtr,"MAP_SPECULAR",12))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexSpecular);
- continue;
- }
- // opacity map
- if (TokenMatch(filePtr,"MAP_OPACITY",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexOpacity);
- continue;
- }
- // emissive map
- if (TokenMatch(filePtr,"MAP_SELFILLUM",13))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexEmissive);
- continue;
- }
- // bump map
- if (TokenMatch(filePtr,"MAP_BUMP",8))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexBump);
- }
- // specular/shininess map
- if (TokenMatch(filePtr,"MAP_SHINESTRENGTH",17))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexShininess);
- continue;
- }
- // number of submaterials
- if (TokenMatch(filePtr,"NUMSUBMTLS",10))
- {
- ParseLV4MeshLong(iNumSubMaterials);
-
- // allocate enough storage
- mat.avSubMaterials.resize(iNumSubMaterials);
- }
- // submaterial chunks
- if (TokenMatch(filePtr,"SUBMATERIAL",11))
- {
-
- unsigned int iIndex = 0;
- ParseLV4MeshLong(iIndex);
-
- if (iIndex >= iNumSubMaterials)
- {
- LogWarning("Out of range: submaterial index is too large");
- iIndex = iNumSubMaterials-1;
- }
-
- // get a reference to the material
- Material& sMat = mat.avSubMaterials[iIndex];
-
- // parse the material block
- ParseLV2MaterialBlock(sMat);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","*MATERIAL");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MapBlock(Texture& map)
-{
- AI_ASE_PARSER_INIT();
-
- // ***********************************************************
- // *BITMAP should not be there if *MAP_CLASS is not BITMAP,
- // but we need to expect that case ... if the path is
- // empty the texture won't be used later.
- // ***********************************************************
- bool parsePath = true;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // type of map
- if (TokenMatch(filePtr,"MAP_CLASS" ,9))
- {
- std::string temp;
- if (!ParseString(temp,"*MAP_CLASS"))
- SkipToNextToken();
- if (temp != "Bitmap")
- {
- DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp);
- parsePath = false;
- }
- continue;
- }
- // path to the texture
- if (parsePath && TokenMatch(filePtr,"BITMAP" ,6))
- {
- if (!ParseString(map.mMapName,"*BITMAP"))
- SkipToNextToken();
-
- if (map.mMapName == "None")
- {
- // Files with 'None' as map name are produced by
- // an Maja to ASE exporter which name I forgot ..
- DefaultLogger::get()->warn("ASE: Skipping invalid map entry");
- map.mMapName = "";
- }
-
- continue;
- }
- // offset on the u axis
- if (TokenMatch(filePtr,"UVW_U_OFFSET" ,12))
- {
- ParseLV4MeshFloat(map.mOffsetU);
- continue;
- }
- // offset on the v axis
- if (TokenMatch(filePtr,"UVW_V_OFFSET" ,12))
- {
- ParseLV4MeshFloat(map.mOffsetV);
- continue;
- }
- // tiling on the u axis
- if (TokenMatch(filePtr,"UVW_U_TILING" ,12))
- {
- ParseLV4MeshFloat(map.mScaleU);
- continue;
- }
- // tiling on the v axis
- if (TokenMatch(filePtr,"UVW_V_TILING" ,12))
- {
- ParseLV4MeshFloat(map.mScaleV);
- continue;
- }
- // rotation around the z-axis
- if (TokenMatch(filePtr,"UVW_ANGLE" ,9))
- {
- ParseLV4MeshFloat(map.mRotation);
- continue;
- }
- // map blending factor
- if (TokenMatch(filePtr,"MAP_AMOUNT" ,10))
- {
- ParseLV4MeshFloat(map.mTextureBlend);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MAP_XXXXXX");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::ParseString(std::string& out,const char* szName)
-{
- char szBuffer[1024];
- if (!SkipSpaces(&filePtr))
- {
-
- sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
- LogWarning(szBuffer);
- return false;
- }
- // there must be '"'
- if ('\"' != *filePtr)
- {
-
- sprintf(szBuffer,"Unable to parse %s block: Strings are expected "
- "to be enclosed in double quotation marks",szName);
- LogWarning(szBuffer);
- return false;
- }
- ++filePtr;
- const char* sz = filePtr;
- while (true)
- {
- if ('\"' == *sz)break;
- else if ('\0' == *sz)
- {
- sprintf(szBuffer,"Unable to parse %s block: Strings are expected to "
- "be enclosed in double quotation marks but EOF was reached before "
- "a closing quotation mark was encountered",szName);
- LogWarning(szBuffer);
- return false;
- }
- sz++;
- }
- out = std::string(filePtr,(uintptr_t)sz-(uintptr_t)filePtr);
- filePtr = sz+1;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // first process common tokens such as node name and transform
- // name of the mesh/node
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- if (!ParseString(node.mName,"*NODE_NAME"))
- SkipToNextToken();
- continue;
- }
- // name of the parent of the node
- if (TokenMatch(filePtr,"NODE_PARENT" ,11) )
- {
- if (!ParseString(node.mParent,"*NODE_PARENT"))
- SkipToNextToken();
- continue;
- }
- // transformation matrix of the node
- if (TokenMatch(filePtr,"NODE_TM" ,7))
- {
- ParseLV2NodeTransformBlock(node);
- continue;
- }
- // animation data of the node
- if (TokenMatch(filePtr,"TM_ANIMATION" ,12))
- {
- ParseLV2AnimationBlock(node);
- continue;
- }
-
- if (node.mType == BaseNode::Light)
- {
- // light settings
- if (TokenMatch(filePtr,"LIGHT_SETTINGS" ,14))
- {
- ParseLV2LightSettingsBlock((ASE::Light&)node);
- continue;
- }
- // type of the light source
- if (TokenMatch(filePtr,"LIGHT_TYPE" ,10))
- {
- if (!ASSIMP_strincmp("omni",filePtr,4))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::OMNI;
- }
- else if (!ASSIMP_strincmp("target",filePtr,6))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::TARGET;
- }
- else if (!ASSIMP_strincmp("free",filePtr,4))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::FREE;
- }
- else if (!ASSIMP_strincmp("directional",filePtr,11))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL;
- }
- else
- {
- LogWarning("Unknown kind of light source");
- }
- continue;
- }
- }
- else if (node.mType == BaseNode::Camera)
- {
- // Camera settings
- if (TokenMatch(filePtr,"CAMERA_SETTINGS" ,15))
- {
- ParseLV2CameraSettingsBlock((ASE::Camera&)node);
- continue;
- }
- else if (TokenMatch(filePtr,"CAMERA_TYPE" ,11))
- {
- if (!ASSIMP_strincmp("target",filePtr,6))
- {
- ((ASE::Camera&)node).mCameraType = ASE::Camera::TARGET;
- }
- else if (!ASSIMP_strincmp("free",filePtr,4))
- {
- ((ASE::Camera&)node).mCameraType = ASE::Camera::FREE;
- }
- else
- {
- LogWarning("Unknown kind of camera");
- }
- continue;
- }
- }
- else if (node.mType == BaseNode::Mesh)
- {
- // mesh data
- // FIX: Older files use MESH_SOFTSKIN
- if (TokenMatch(filePtr,"MESH" ,4) ||
- TokenMatch(filePtr,"MESH_SOFTSKIN",13))
- {
- ParseLV2MeshBlock((ASE::Mesh&)node);
- continue;
- }
- // mesh material index
- if (TokenMatch(filePtr,"MATERIAL_REF" ,12))
- {
- ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex);
- continue;
- }
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2CameraSettingsBlock(ASE::Camera& camera)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"CAMERA_NEAR" ,11))
- {
- ParseLV4MeshFloat(camera.mNear);
- continue;
- }
- if (TokenMatch(filePtr,"CAMERA_FAR" ,10))
- {
- ParseLV4MeshFloat(camera.mFar);
- continue;
- }
- if (TokenMatch(filePtr,"CAMERA_FOV" ,10))
- {
- ParseLV4MeshFloat(camera.mFOV);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","CAMERA_SETTINGS");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"LIGHT_COLOR" ,11))
- {
- ParseLV4MeshFloatTriple(&light.mColor.r);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_INTENS" ,12))
- {
- ParseLV4MeshFloat(light.mIntensity);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_HOTSPOT" ,13))
- {
- ParseLV4MeshFloat(light.mAngle);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_FALLOFF" ,13))
- {
- ParseLV4MeshFloat(light.mFalloff);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","LIGHT_SETTINGS");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- ASE::Animation* anim = &mesh.mAnim;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- std::string temp;
- if (!ParseString(temp,"*NODE_NAME"))
- SkipToNextToken();
-
- // If the name of the node contains .target it
- // represents an animated camera or spot light
- // target.
- if (std::string::npos != temp.find(".Target"))
- {
- if ((mesh.mType != BaseNode::Camera || ((ASE::Camera&)mesh).mCameraType != ASE::Camera::TARGET) &&
- ( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET))
- {
-
- DefaultLogger::get()->error("ASE: Found target animation channel "
- "but the node is neither a camera nor a spot light");
- anim = NULL;
- }
- else anim = &mesh.mTargetAnim;
- }
- continue;
- }
-
- // position keyframes
- if (TokenMatch(filePtr,"CONTROL_POS_TRACK" ,17) ||
- TokenMatch(filePtr,"CONTROL_POS_BEZIER" ,18) ||
- TokenMatch(filePtr,"CONTROL_POS_TCB" ,15))
- {
- if (!anim)SkipSection();
- else ParseLV3PosAnimationBlock(*anim);
- continue;
- }
- // scaling keyframes
- if (TokenMatch(filePtr,"CONTROL_SCALE_TRACK" ,19) ||
- TokenMatch(filePtr,"CONTROL_SCALE_BEZIER" ,20) ||
- TokenMatch(filePtr,"CONTROL_SCALE_TCB" ,17))
- {
- if (!anim || anim == &mesh.mTargetAnim)
- {
- // Target animation channels may have no rotation channels
- DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
- SkipSection();
- }
- else ParseLV3ScaleAnimationBlock(*anim);
- continue;
- }
- // rotation keyframes
- if (TokenMatch(filePtr,"CONTROL_ROT_TRACK" ,17) ||
- TokenMatch(filePtr,"CONTROL_ROT_BEZIER" ,18) ||
- TokenMatch(filePtr,"CONTROL_ROT_TCB" ,15))
- {
- if (!anim || anim == &mesh.mTargetAnim)
- {
- // Target animation channels may have no rotation channels
- DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
- SkipSection();
- }
- else ParseLV3RotAnimationBlock(*anim);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","TM_ANIMATION");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
-
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the three floats -
- // we ignore the dditional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
- {
- b = true;
- anim.mScalingType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_SCALE_KEY" ,24))
- {
- b = true;
- anim.mScalingType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_SCALE_KEY" ,21))
- {
- b = true;
- anim.mScalingType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyScaling.push_back(aiVectorKey());
- aiVectorKey& key = anim.akeyScaling.back();
- ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
- key.mTime = (double)iIndex;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the three floats -
- // we ignore the dditional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
- {
- b = true;
- anim.mPositionType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_POS_KEY" ,22))
- {
- b = true;
- anim.mPositionType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_POS_KEY" ,19))
- {
- b = true;
- anim.mPositionType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyPositions.push_back(aiVectorKey());
- aiVectorKey& key = anim.akeyPositions.back();
- ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
- key.mTime = (double)iIndex;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the floats -
- // we ignore the dditional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
- {
- b = true;
- anim.mRotationType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_ROT_KEY" ,22))
- {
- b = true;
- anim.mRotationType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_ROT_KEY" ,19))
- {
- b = true;
- anim.mRotationType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyRotations.push_back(aiQuatKey());
- aiQuatKey& key = anim.akeyRotations.back();
- aiVector3D v;float f;
- ParseLV4MeshFloatTriple(&v.x,iIndex);
- ParseLV4MeshFloat(f);
- key.mTime = (double)iIndex;
- key.mValue = aiQuaternion(v,f);
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_ROT_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
-{
- AI_ASE_PARSER_INIT();
- int mode = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // name of the node
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- std::string temp;
- if (!ParseString(temp,"*NODE_NAME"))
- SkipToNextToken();
-
- std::string::size_type s;
- if (temp == mesh.mName)
- {
- mode = 1;
- }
- else if (std::string::npos != (s = temp.find(".Target")) &&
- mesh.mName == temp.substr(0,s))
- {
- // This should be either a target light or a target camera
- if ( (mesh.mType == BaseNode::Light && ((ASE::Light&)mesh) .mLightType == ASE::Light::TARGET) ||
- (mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET))
- {
- mode = 2;
- }
- else DefaultLogger::get()->error("ASE: Ignoring target transform, "
- "this is no spot light or target camera");
- }
- else
- {
- DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
- // mode = 0
- }
- continue;
- }
- if (mode)
- {
- // fourth row of the transformation matrix - and also the
- // only information here that is interesting for targets
- if (TokenMatch(filePtr,"TM_ROW3" ,7))
- {
- ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
- continue;
- }
- if (mode == 1)
- {
- // first row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW0" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[0]);
- continue;
- }
- // second row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW1" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[1]);
- continue;
- }
- // third row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW2" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[2]);
- continue;
- }
- // inherited position axes
- if (TokenMatch(filePtr,"INHERIT_POS" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
- continue;
- }
- // inherited rotation axes
- if (TokenMatch(filePtr,"INHERIT_ROT" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
- continue;
- }
- // inherited scaling axes
- if (TokenMatch(filePtr,"INHERIT_SCL" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
- continue;
- }
- }
- }
- }
- AI_ASE_HANDLE_SECTION("2","*NODE_TM");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumVertices = 0;
- unsigned int iNumFaces = 0;
- unsigned int iNumTVertices = 0;
- unsigned int iNumTFaces = 0;
- unsigned int iNumCVertices = 0;
- unsigned int iNumCFaces = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // Number of vertices in the mesh
- if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
- {
- ParseLV4MeshLong(iNumVertices);
- continue;
- }
- // Number of texture coordinates in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumTVertices);
- continue;
- }
- // Number of vertex colors in the mesh
- if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumCVertices);
- continue;
- }
- // Number of regular faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMFACES" ,13))
- {
- ParseLV4MeshLong(iNumFaces);
- continue;
- }
- // Number of UVWed faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
- {
- ParseLV4MeshLong(iNumTFaces);
- continue;
- }
- // Number of colored faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMCVFACES" ,15))
- {
- ParseLV4MeshLong(iNumCFaces);
- continue;
- }
- // mesh vertex list block
- if (TokenMatch(filePtr,"MESH_VERTEX_LIST" ,16))
- {
- ParseLV3MeshVertexListBlock(iNumVertices,mesh);
- continue;
- }
- // mesh face list block
- if (TokenMatch(filePtr,"MESH_FACE_LIST" ,14))
- {
- ParseLV3MeshFaceListBlock(iNumFaces,mesh);
- continue;
- }
- // mesh texture vertex list block
- if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
- {
- ParseLV3MeshTListBlock(iNumTVertices,mesh);
- continue;
- }
- // mesh texture face block
- if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
- {
- ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
- continue;
- }
- // mesh color vertex list block
- if (TokenMatch(filePtr,"MESH_CVERTLIST" ,14))
- {
- ParseLV3MeshCListBlock(iNumCVertices,mesh);
- continue;
- }
- // mesh color face block
- if (TokenMatch(filePtr,"MESH_CFACELIST" ,14))
- {
- ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
- continue;
- }
- // mesh normals
- if (TokenMatch(filePtr,"MESH_NORMALS" ,12))
- {
- ParseLV3MeshNormalListBlock(mesh);
- continue;
- }
- // another mesh UV channel ...
- if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19))
- {
-
- unsigned int iIndex = 0;
- ParseLV4MeshLong(iIndex);
-
- if (iIndex < 2)
- {
- LogWarning("Mapping channel has an invalid index. Skipping UV channel");
- // skip it ...
- SkipSection();
- }
- if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS)
- {
- LogWarning("Too many UV channels specified. Skipping channel ..");
- // skip it ...
- SkipSection();
- }
- else
- {
- // parse the mapping channel
- ParseLV3MappingChannel(iIndex-1,mesh);
- }
- continue;
- }
- // mesh animation keyframe. Not supported
- if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
- {
-
- LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. "
- "Keyframe animation is not supported by Assimp, this element "
- "will be ignored");
- //SkipSection();
- continue;
- }
- if (TokenMatch(filePtr,"MESH_WEIGHTS" ,12))
- {
- ParseLV3MeshWeightsBlock(mesh);continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","*MESH");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumVertices = 0, iNumBones = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Number of bone vertices ...
- if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
- {
- ParseLV4MeshLong(iNumVertices);
- continue;
- }
- // Number of bones
- if (TokenMatch(filePtr,"MESH_NUMBONE" ,11))
- {
- ParseLV4MeshLong(iNumBones);
- continue;
- }
- // parse the list of bones
- if (TokenMatch(filePtr,"MESH_BONE_LIST" ,14))
- {
- ParseLV4MeshBones(iNumBones,mesh);
- continue;
- }
- // parse the list of bones vertices
- if (TokenMatch(filePtr,"MESH_BONE_VERTEX_LIST" ,21) )
- {
- ParseLV4MeshBonesVertices(iNumVertices,mesh);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_WEIGHTS");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- mesh.mBones.resize(iNumBones);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Mesh bone with name ...
- if (TokenMatch(filePtr,"MESH_BONE_NAME" ,16))
- {
- // parse an index ...
- if (SkipSpaces(&filePtr))
- {
- unsigned int iIndex = strtol10(filePtr,&filePtr);
- if (iIndex >= iNumBones)
- {
- continue;
- LogWarning("Bone index is out of bounds");
- }
- if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
- SkipToNextToken();
- continue;
- }
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_BONE_LIST");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- mesh.mBoneVertices.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Mesh bone vertex
- if (TokenMatch(filePtr,"MESH_BONE_VERTEX" ,16))
- {
- // read the vertex index
- unsigned int iIndex = strtol10(filePtr,&filePtr);
- if (iIndex >= mesh.mPositions.size())
- {
- iIndex = (unsigned int)mesh.mPositions.size()-1;
- LogWarning("Bone vertex index is out of bounds. Using the largest valid "
- "bone vertex index instead");
- }
-
- // --- ignored
- float afVert[3];
- ParseLV4MeshFloatTriple(afVert);
-
- std::pair<int,float> pairOut;
- while (true)
- {
- // first parse the bone index ...
- if (!SkipSpaces(&filePtr))break;
- pairOut.first = strtol10(filePtr,&filePtr);
-
- // then parse the vertex weight
- if (!SkipSpaces(&filePtr))break;
- filePtr = fast_atof_move(filePtr,pairOut.second);
-
- // -1 marks unused entries
- if (-1 != pairOut.first)
- {
- mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut);
- }
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("4","*MESH_BONE_VERTEX");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshVertexListBlock(
- unsigned int iNumVertices, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.mPositions.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_VERTEX" ,11))
- {
-
- aiVector3D vTemp;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Invalid vertex index. It will be ignored");
- }
- else mesh.mPositions[iIndex] = vTemp;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_VERTEX_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the face array
- mesh.mFaces.resize(iNumFaces);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_FACE" ,9))
- {
-
- ASE::Face mFace;
- ParseLV4MeshFace(mFace);
-
- if (mFace.iFace >= iNumFaces)
- {
- LogWarning("Face has an invalid index. It will be ignored");
- }
- else mesh.mFaces[mFace.iFace] = mFace;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_FACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
- ASE::Mesh& mesh, unsigned int iChannel)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.amTexCoords[iChannel].resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_TVERT" ,10))
- {
- aiVector3D vTemp;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Tvertex has an invalid index. It will be ignored");
- }
- else mesh.amTexCoords[iChannel][iIndex] = vTemp;
-
- if (0.0f != vTemp.z)
- {
- // we need 3 coordinate channels
- mesh.mNumUVComponents[iChannel] = 3;
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_TVERT_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
- ASE::Mesh& mesh, unsigned int iChannel)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_TFACE" ,10))
- {
- unsigned int aiValues[3];
- unsigned int iIndex = 0;
-
- ParseLV4MeshLongTriple(aiValues,iIndex);
- if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
- {
- LogWarning("UV-Face has an invalid index. It will be ignored");
- }
- else
- {
- // copy UV indices
- mesh.mFaces[iIndex].amUVIndices[iChannel][0] = aiValues[0];
- mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1];
- mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2];
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_TFACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumTVertices = 0;
- unsigned int iNumTFaces = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Number of texture coordinates in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumTVertices);
- continue;
- }
- // Number of UVWed faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
- {
- ParseLV4MeshLong(iNumTFaces);
- continue;
- }
- // mesh texture vertex list block
- if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
- {
- ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
- continue;
- }
- // mesh texture face block
- if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
- {
- ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_MAPPING_CHANNEL");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.mVertexColors.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_VERTCOL" ,12))
- {
- aiColor4D vTemp;
- vTemp.a = 1.0f;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.r,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Vertex color has an invalid index. It will be ignored");
- }
- else mesh.mVertexColors[iIndex] = vTemp;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_CVERTEX_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_CFACE" ,11))
- {
- unsigned int aiValues[3];
- unsigned int iIndex = 0;
-
- ParseLV4MeshLongTriple(aiValues,iIndex);
- if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
- {
- LogWarning("UV-Face has an invalid index. It will be ignored");
- }
- else
- {
- // copy color indices
- mesh.mFaces[iIndex].mColorIndices[0] = aiValues[0];
- mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1];
- mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2];
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_CFACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
-{
- AI_ASE_PARSER_INIT();
-
- // Allocate enough storage for the normals
- sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
- unsigned int index, faceIdx = 0xffffffff;
-
- // FIXME: rewrite this and find out how to interpret the normals
- // correctly. This is crap.
-
- // Smooth the vertex and face normals together. The result
- // will be edgy then, but otherwise everything would be soft ...
- while (true) {
- if ('*' == *filePtr) {
- ++filePtr;
- if (faceIdx != 0xffffffff && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17)) {
- aiVector3D vNormal;
- ParseLV4MeshFloatTriple(&vNormal.x,index);
- if (faceIdx >= sMesh.mFaces.size())
- continue;
-
- // Make sure we assign it to the correct face
- const ASE::Face& face = sMesh.mFaces[faceIdx];
- if (index == face.mIndices[0])
- index = 0;
- else if (index == face.mIndices[1])
- index = 1;
- else if (index == face.mIndices[2])
- index = 2;
- else {
- DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
- continue;
- }
- // We'll renormalize later
- sMesh.mNormals[faceIdx*3+index] += vNormal;
- continue;
- }
- if (TokenMatch(filePtr,"MESH_FACENORMAL",15)) {
- aiVector3D vNormal;
- ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
-
- if (faceIdx >= sMesh.mFaces.size()) {
- DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
- continue;
- }
-
- // We'll renormalize later
- sMesh.mNormals[faceIdx*3] += vNormal;
- sMesh.mNormals[faceIdx*3+1] += vNormal;
- sMesh.mNormals[faceIdx*3+2] += vNormal;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_NORMALS");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFace(ASE::Face& out)
-{
- // skip spaces and tabs
- if (!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
- SkipToNextToken();
- return;
- }
-
- // parse the face index
- out.iFace = strtol10(filePtr,&filePtr);
-
- // next character should be ':'
- if (!SkipSpaces(&filePtr))
- {
- // FIX: there are some ASE files which haven't got : here ....
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
- SkipToNextToken();
- return;
- }
- // FIX: There are some ASE files which haven't got ':' here
- if (':' == *filePtr)++filePtr;
-
- // Parse all mesh indices
- for (unsigned int i = 0; i < 3;++i)
- {
- unsigned int iIndex = 0;
- if (!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
- SkipToNextToken();
- return;
- }
- switch (*filePtr)
- {
- case 'A':
- case 'a':
- break;
- case 'B':
- case 'b':
- iIndex = 1;
- break;
- case 'C':
- case 'c':
- iIndex = 2;
- break;
- default:
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
- "A,B or C expected [#3]");
- SkipToNextToken();
- return;
- };
- ++filePtr;
-
- // next character should be ':'
- if (!SkipSpaces(&filePtr) || ':' != *filePtr)
- {
- LogWarning("Unable to parse *MESH_FACE Element: "
- "Unexpected EOL. \':\' expected [#2]");
- SkipToNextToken();
- return;
- }
-
- ++filePtr;
- if (!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
- "Vertex index ecpected [#4]");
- SkipToNextToken();
- return;
- }
- out.mIndices[iIndex] = strtol10(filePtr,&filePtr);
- }
-
- // now we need to skip the AB, BC, CA blocks.
- while (true)
- {
- if ('*' == *filePtr)break;
- if (IsLineEnd(*filePtr))
- {
- //iLineNumber++;
- return;
- }
- filePtr++;
- }
-
- // parse the smoothing group of the face
- if (TokenMatch(filePtr,"*MESH_SMOOTHING",15))
- {
- if (!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_SMOOTHING Element: "
- "Unexpected EOL. Smoothing group(s) expected [#5]");
- SkipToNextToken();
- return;
- }
-
- // Parse smoothing groups until we don't anymore see commas
- // FIX: There needn't always be a value, sad but true
- while (true)
- {
- if (*filePtr < '9' && *filePtr >= '0')
- {
- out.iSmoothGroup |= (1 << strtol10(filePtr,&filePtr));
- }
- SkipSpaces(&filePtr);
- if (',' != *filePtr)
- {
- break;
- }
- ++filePtr;
- SkipSpaces(&filePtr);
- }
- }
-
- // *MESH_MTLID is optional, too
- while (true)
- {
- if ('*' == *filePtr)break;
- if (IsLineEnd(*filePtr))
- {
- return;
- }
- filePtr++;
- }
-
- if (TokenMatch(filePtr,"*MESH_MTLID",11))
- {
- if (!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
- "Material index expected [#6]");
- SkipToNextToken();
- return;
- }
- out.iMaterial = strtol10(filePtr,&filePtr);
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
-{
- ai_assert(NULL != apOut);
-
- for (unsigned int i = 0; i < 3;++i)
- ParseLV4MeshLong(apOut[i]);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut)
-{
- ai_assert(NULL != apOut);
-
- // parse the index
- ParseLV4MeshLong(rIndexOut);
-
- // parse the three others
- ParseLV4MeshLongTriple(apOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
-{
- ai_assert(NULL != apOut);
-
- // parse the index
- ParseLV4MeshLong(rIndexOut);
-
- // parse the three others
- ParseLV4MeshFloatTriple(apOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(float* apOut)
-{
- ai_assert(NULL != apOut);
-
- for (unsigned int i = 0; i < 3;++i)
- ParseLV4MeshFloat(apOut[i]);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloat(float& fOut)
-{
- // skip spaces and tabs
- if (!SkipSpaces(&filePtr))
- {
- // LOG
- LogWarning("Unable to parse float: unexpected EOL [#1]");
- fOut = 0.0f;
- ++iLineNumber;
- return;
- }
- // parse the first float
- filePtr = fast_atof_move(filePtr,fOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLong(unsigned int& iOut)
-{
- // Skip spaces and tabs
- if (!SkipSpaces(&filePtr))
- {
- // LOG
- LogWarning("Unable to parse long: unexpected EOL [#1]");
- iOut = 0;
- ++iLineNumber;
- return;
- }
- // parse the value
- iOut = strtol10(filePtr,&filePtr);
-}
diff --git a/3rdparty/assimp/code/ASEParser.h b/3rdparty/assimp/code/ASEParser.h
deleted file mode 100644
index a221a8e8..00000000
--- a/3rdparty/assimp/code/ASEParser.h
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines the helper data structures for importing ASE files */
-#ifndef AI_ASEFILEHELPER_H_INC
-#define AI_ASEFILEHELPER_H_INC
-
-// STL/CRT headers
-#include <string>
-#include <vector>
-#include <list>
-
-// public ASSIMP headers
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-// for some helper routines like IsSpace()
-#include "ParsingUtils.h"
-#include "qnan.h"
-
-// ASE is quite similar to 3ds. We can reuse some structures
-#include "3DSLoader.h"
-
-namespace Assimp {
-namespace ASE {
-
-using namespace D3DS;
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing an ASE material */
-struct Material : public D3DS::Material
-{
- //! Default constructor
- Material() : pcInstance(NULL), bNeed (false)
- {}
-
- //! Contains all sub materials of this material
- std::vector<Material> avSubMaterials;
-
- //! MaterialHelper object
- MaterialHelper* pcInstance;
-
- //! Can we remove this material?
- bool bNeed;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file face */
-struct Face : public FaceWithSmoothingGroup
-{
- //! Default constructor. Initializes everything with 0
- Face()
- {
- mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
- }
-
- iMaterial = DEFAULT_MATINDEX;
- iFace = 0;
- }
-
- //! special value to indicate that no material index has
- //! been assigned to a face. The default material index
- //! will replace this value later.
- static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
-
-
-
- //! Indices into each list of texture coordinates
- unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
-
- //! Index into the list of vertex colors
- unsigned int mColorIndices[3];
-
- //! (Sub)Material index to be assigned to this face
- unsigned int iMaterial;
-
- //! Index of the face. It is not specified whether it is
- //! a requirement of the file format that all faces are
- //! written in sequential order, so we have to expect this case
- unsigned int iFace;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file bone */
-struct Bone
-{
- //! Constructor
- Bone()
- {
- static int iCnt = 0;
-
- // Generate a default name for the bone
- char szTemp[128];
- ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Construction from an existing name
- Bone( const std::string& name)
- : mName (name)
- {}
-
- //! Name of the bone
- std::string mName;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file bone vertex */
-struct BoneVertex
-{
- //! Bone and corresponding vertex weight.
- //! -1 for unrequired bones ....
- std::vector<std::pair<int,float> > mBoneWeights;
-
- //! Position of the bone vertex.
- //! MUST be identical to the vertex position
- //aiVector3D mPosition;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file animation */
-struct Animation
-{
- enum Type
- {
- TRACK = 0x0,
- BEZIER = 0x1,
- TCB = 0x2
- } mRotationType, mScalingType, mPositionType;
-
- Animation()
- : mRotationType (TRACK)
- , mScalingType (TRACK)
- , mPositionType (TRACK)
- {}
-
- //! List of track rotation keyframes
- std::vector< aiQuatKey > akeyRotations;
-
- //! List of track position keyframes
- std::vector< aiVectorKey > akeyPositions;
-
- //! List of track scaling keyframes
- std::vector< aiVectorKey > akeyScaling;
-
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent the inheritance information of an ASE node */
-struct InheritanceInfo
-{
- //! Default constructor
- InheritanceInfo()
- {
- // set the inheritance flag for all axes by default to true
- for (unsigned int i = 0; i < 3;++i)
- abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
- }
-
- //! Inherit the parent's position?, axis order is x,y,z
- bool abInheritPosition[3];
-
- //! Inherit the parent's rotation?, axis order is x,y,z
- bool abInheritRotation[3];
-
- //! Inherit the parent's scaling?, axis order is x,y,z
- bool abInheritScaling[3];
-};
-
-// ---------------------------------------------------------------------------
-/** Represents an ASE file node. Base class for mesh, light and cameras */
-struct BaseNode
-{
- enum Type {Light, Camera, Mesh, Dummy} mType;
-
- //! Constructor. Creates a default name for the node
- BaseNode(Type _mType)
- : mType (_mType)
- , mProcessed (false)
- {
- // generate a default name for the node
- static int iCnt = 0;
- char szTemp[128]; // should be sufficiently large
- ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
- mName = szTemp;
-
- // Set mTargetPosition to qnan
- const float qnan = get_qnan();
- mTargetPosition.x = qnan;
- }
-
- //! Name of the mesh
- std::string mName;
-
- //! Name of the parent of the node
- //! "" if there is no parent ...
- std::string mParent;
-
- //! Transformation matrix of the node
- aiMatrix4x4 mTransform;
-
- //! Target position (target lights and cameras)
- aiVector3D mTargetPosition;
-
- //! Specifies which axes transformations a node inherits
- //! from its parent ...
- InheritanceInfo inherit;
-
- //! Animation channels for the node
- Animation mAnim;
-
- //! Needed for lights and cameras: target animation channel
- //! Should contain position keys only.
- Animation mTargetAnim;
-
- bool mProcessed;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file mesh */
-struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
-{
- //! Constructor.
- Mesh()
- : BaseNode (BaseNode::Mesh)
- , bSkip (false)
- {
- // use 2 texture vertex components by default
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- this->mNumUVComponents[c] = 2;
-
- // setup the default material index by default
- iMaterialIndex = Face::DEFAULT_MATINDEX;
- }
-
- //! List of all texture coordinate sets
- std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- //! List of all vertex color sets.
- std::vector<aiColor4D> mVertexColors;
-
- //! List of all bone vertices
- std::vector<BoneVertex> mBoneVertices;
-
- //! List of all bones
- std::vector<Bone> mBones;
-
- //! Material index of the mesh
- unsigned int iMaterialIndex;
-
- //! Number of vertex components for each UVW set
- unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- //! used internally
- bool bSkip;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE light source */
-struct Light : public BaseNode
-{
- enum LightType
- {
- OMNI,
- TARGET,
- FREE,
- DIRECTIONAL
- };
-
- //! Constructor.
- Light()
- : BaseNode (BaseNode::Light)
- , mLightType (OMNI)
- , mColor (1.f,1.f,1.f)
- , mIntensity (1.f) // light is white by default
- , mAngle (45.f)
- , mFalloff (0.f)
- {
- }
-
- LightType mLightType;
- aiColor3D mColor;
- float mIntensity;
- float mAngle; // in degrees
- float mFalloff;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE camera */
-struct Camera : public BaseNode
-{
- enum CameraType
- {
- FREE,
- TARGET
- };
-
- //! Constructor
- Camera()
- : BaseNode (BaseNode::Camera)
- , mFOV (0.75f) // in radians
- , mNear (0.1f)
- , mFar (1000.f) // could be zero
- , mCameraType (FREE)
- {
- }
-
- float mFOV, mNear, mFar;
- CameraType mCameraType;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE helper object (dummy) */
-struct Dummy : public BaseNode
-{
- //! Constructor
- Dummy()
- : BaseNode (BaseNode::Dummy)
- {
- }
-};
-
-// Parameters to Parser::Parse()
-#define AI_ASE_NEW_FILE_FORMAT 200
-#define AI_ASE_OLD_FILE_FORMAT 110
-
-// Internally we're a little bit more tolerant
-#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
-#define AI_ASE_IS_OLD_FILE_FORMAT() (iFileFormat < 200)
-
-// -------------------------------------------------------------------------------
-/** \brief Class to parse ASE files
- */
-class Parser
-{
-
-private:
-
- Parser() {}
-
-public:
-
- // -------------------------------------------------------------------
- //! Construct a parser from a given input file which is
- //! guaranted to be terminated with zero.
- //! @param szFile Input file
- //! @param fileFormatDefault Assumed file format version. If the
- //! file format is specified in the file the new value replaces
- //! the default value.
- Parser (const char* szFile, unsigned int fileFormatDefault);
-
- // -------------------------------------------------------------------
- //! Parses the file into the parsers internal representation
- void Parse();
-
-
-private:
-
- // -------------------------------------------------------------------
- //! Parse the *SCENE block in a file
- void ParseLV1SceneBlock();
-
- // -------------------------------------------------------------------
- //! Parse the *MESH_SOFTSKINVERTS block in a file
- void ParseLV1SoftSkinBlock();
-
- // -------------------------------------------------------------------
- //! Parse the *MATERIAL_LIST block in a file
- void ParseLV1MaterialListBlock();
-
- // -------------------------------------------------------------------
- //! Parse a *<xxx>OBJECT block in a file
- //! \param mesh Node to be filled
- void ParseLV1ObjectBlock(BaseNode& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MATERIAL blocks in a material list
- //! \param mat Material structure to be filled
- void ParseLV2MaterialBlock(Material& mat);
-
- // -------------------------------------------------------------------
- //! Parse a *NODE_TM block in a file
- //! \param mesh Node (!) object to be filled
- void ParseLV2NodeTransformBlock(BaseNode& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *TM_ANIMATION block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV2AnimationBlock(BaseNode& mesh);
- void ParseLV3PosAnimationBlock(ASE::Animation& anim);
- void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
- void ParseLV3RotAnimationBlock(ASE::Animation& anim);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV2MeshBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *LIGHT_SETTINGS block in a file
- //! \param light Light object to be filled
- void ParseLV2LightSettingsBlock(Light& light);
-
- // -------------------------------------------------------------------
- //! Parse a *CAMERA_SETTINGS block in a file
- //! \param cam Camera object to be filled
- void ParseLV2CameraSettingsBlock(Camera& cam);
-
- // -------------------------------------------------------------------
- //! Parse the *MAP_XXXXXX blocks in a material
- //! \param map Texture structure to be filled
- void ParseLV3MapBlock(Texture& map);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERTEX_LIST block in a file
- //! \param iNumVertices Value of *MESH_NUMVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshVertexListBlock(
- unsigned int iNumVertices,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_FACE_LIST block in a file
- //! \param iNumFaces Value of *MESH_NUMFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshFaceListBlock(
- unsigned int iNumFaces,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TVERT_LIST block in a file
- //! \param iNumVertices Value of *MESH_NUMTVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- //! \param iChannel Output UVW channel
- void ParseLV3MeshTListBlock(
- unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACELIST block in a file
- //! \param iNumFaces Value of *MESH_NUMTVFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- //! \param iChannel Output UVW channel
- void ParseLV3MeshTFaceListBlock(
- unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0);
-
- // -------------------------------------------------------------------
- //! Parse an additional mapping channel
- //! (specified via *MESH_MAPPINGCHANNEL)
- //! \param iChannel Channel index to be filled
- //! \param mesh Mesh object to be filled
- void ParseLV3MappingChannel(
- unsigned int iChannel, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_CVERTLIST block in a file
- //! \param iNumVertices Value of *MESH_NUMCVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshCListBlock(
- unsigned int iNumVertices, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_CFACELIST block in a file
- //! \param iNumFaces Value of *MESH_NUMCVFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshCFaceListBlock(
- unsigned int iNumFaces, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_NORMALS block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshNormalListBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_WEIGHTSblock in a file
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshWeightsBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse the bone list of a file
- //! \param mesh Mesh object to be filled
- //! \param iNumBones Number of bones in the mesh
- void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse the bone vertices list of a file
- //! \param mesh Mesh object to be filled
- //! \param iNumVertices Number of vertices to be parsed
- void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_FACE block in a file
- //! \param out receive the face data
- void ParseLV4MeshFace(ASE::Face& out);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERT block in a file
- //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
- //! \param apOut Output buffer (3 floats)
- //! \param rIndexOut Output index
- void ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERT block in a file
- //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
- //! \param apOut Output buffer (3 floats)
- void ParseLV4MeshFloatTriple(float* apOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACE block in a file
- //! (also works for MESH_CFACE)
- //! \param apOut Output buffer (3 ints)
- //! \param rIndexOut Output index
- void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACE block in a file
- //! (also works for MESH_CFACE)
- //! \param apOut Output buffer (3 ints)
- void ParseLV4MeshLongTriple(unsigned int* apOut);
-
- // -------------------------------------------------------------------
- //! Parse a single float element
- //! \param fOut Output float
- void ParseLV4MeshFloat(float& fOut);
-
- // -------------------------------------------------------------------
- //! Parse a single int element
- //! \param iOut Output integer
- void ParseLV4MeshLong(unsigned int& iOut);
-
- // -------------------------------------------------------------------
- //! Skip everything to the next: '*' or '\0'
- bool SkipToNextToken();
-
- // -------------------------------------------------------------------
- //! Skip the current section until the token after the closing }.
- //! This function handles embedded subsections correctly
- bool SkipSection();
-
- // -------------------------------------------------------------------
- //! Output a warning to the logger
- //! \param szWarn Warn message
- void LogWarning(const char* szWarn);
-
- // -------------------------------------------------------------------
- //! Output a message to the logger
- //! \param szWarn Message
- void LogInfo(const char* szWarn);
-
- // -------------------------------------------------------------------
- //! Output an error to the logger
- //! \param szWarn Error message
- void LogError(const char* szWarn);
-
- // -------------------------------------------------------------------
- //! Parse a string, enclosed in double quotation marks
- //! \param out Output string
- //! \param szName Name of the enclosing element -> used in error
- //! messages.
- //! \return false if an error occured
- bool ParseString(std::string& out,const char* szName);
-
-public:
-
- //! Pointer to current data
- const char* filePtr;
-
- //! background color to be passed to the viewer
- //! QNAN if none was found
- aiColor3D m_clrBackground;
-
- //! Base ambient color to be passed to all materials
- //! QNAN if none was found
- aiColor3D m_clrAmbient;
-
- //! List of all materials found in the file
- std::vector<Material> m_vMaterials;
-
- //! List of all meshes found in the file
- std::vector<Mesh> m_vMeshes;
-
- //! List of all dummies found in the file
- std::vector<Dummy> m_vDummies;
-
- //! List of all lights found in the file
- std::vector<Light> m_vLights;
-
- //! List of all cameras found in the file
- std::vector<Camera> m_vCameras;
-
- //! Current line in the file
- unsigned int iLineNumber;
-
- //! First frame
- unsigned int iFirstFrame;
-
- //! Last frame
- unsigned int iLastFrame;
-
- //! Frame speed - frames per second
- unsigned int iFrameSpeed;
-
- //! Ticks per frame
- unsigned int iTicksPerFrame;
-
- //! true if the last character read was an end-line character
- bool bLastWasEndLine;
-
- //! File format version
- unsigned int iFileFormat;
-};
-
-
-} // Namespace ASE
-} // Namespace ASSIMP
-
-#endif // !! include guard
diff --git a/3rdparty/assimp/code/Assimp.cpp b/3rdparty/assimp/code/Assimp.cpp
deleted file mode 100644
index c00dc63b..00000000
--- a/3rdparty/assimp/code/Assimp.cpp
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file Assimp.cpp
- * @brief Implementation of the Plain-C API
- */
-
-#include "AssimpPCH.h"
-#include "../include/assimp.h"
-#include "../include/aiFileIO.h"
-
-#include "GenericProperty.h"
-
-// ------------------------------------------------------------------------------------------------
-#ifdef AI_C_THREADSAFE
-# include <boost/thread/thread.hpp>
-# include <boost/thread/mutex.hpp>
-#endif
-// ------------------------------------------------------------------------------------------------
-using namespace Assimp;
-
-namespace Assimp
-{
- /** Stores the importer objects for all active import processes */
- typedef std::map<const aiScene*, Assimp::Importer*> ImporterMap;
-
- /** Stores the LogStream objects for all active C log streams */
- struct mpred {
- bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
- return s0.callback<s1.callback&&s0.user<s1.user;
- }
- };
- typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
-
- /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
- typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
-
- /** Local storage of all active import processes */
- static ImporterMap gActiveImports;
-
- /** Local storage of all active log streams */
- static LogStreamMap gActiveLogStreams;
-
- /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
- static PredefLogStreamMap gPredefinedStreams;
-
- /** Error message of the last failed import process */
- static std::string gLastErrorString;
-
- /** Verbose logging active or not? */
- static aiBool gVerboseLogging = false;
-}
-
-/** Configuration properties */
-static ImporterPimpl::IntPropertyMap gIntProperties;
-static ImporterPimpl::FloatPropertyMap gFloatProperties;
-static ImporterPimpl::StringPropertyMap gStringProperties;
-
-#ifdef AI_C_THREADSAFE
-/** Global mutex to manage the access to the importer map */
-static boost::mutex gMutex;
-
-/** Global mutex to manage the access to the logstream map */
-static boost::mutex gLogStreamMutex;
-#endif
-
-class CIOSystemWrapper;
-class CIOStreamWrapper;
-
-// ------------------------------------------------------------------------------------------------
-// Custom IOStream implementation for the C-API
-class CIOStreamWrapper : public IOStream
-{
- friend class CIOSystemWrapper;
-public:
-
- CIOStreamWrapper(aiFile* pFile)
- : mFile(pFile)
- {}
-
- // ...................................................................
- size_t Read(void* pvBuffer,
- size_t pSize,
- size_t pCount
- ){
- // need to typecast here as C has no void*
- return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
- }
-
- // ...................................................................
- size_t Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount
- ){
- // need to typecast here as C has no void*
- return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
- }
-
- // ...................................................................
- aiReturn Seek(size_t pOffset,
- aiOrigin pOrigin
- ){
- return mFile->SeekProc(mFile,pOffset,pOrigin);
- }
-
- // ...................................................................
- size_t Tell(void) const {
- return mFile->TellProc(mFile);
- }
-
- // ...................................................................
- size_t FileSize() const {
- return mFile->FileSizeProc(mFile);
- }
-
- // ...................................................................
- void Flush () {
- return mFile->FlushProc(mFile);
- }
-
-private:
- aiFile* mFile;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Custom IOStream implementation for the C-API
-class CIOSystemWrapper : public IOSystem
-{
-public:
- CIOSystemWrapper(aiFileIO* pFile)
- : mFileSystem(pFile)
- {}
-
- // ...................................................................
- bool Exists( const char* pFile) const {
- CIOSystemWrapper* pip = const_cast<CIOSystemWrapper*>(this);
- IOStream* p = pip->Open(pFile);
- if (p){
- pip->Close(p);
- return true;
- }
- return false;
- }
-
- // ...................................................................
- char getOsSeparator() const {
-#ifndef _WIN32
- return '/';
-#else
- return '\\';
-#endif
- }
-
- // ...................................................................
- IOStream* Open(const char* pFile,const char* pMode = "rb") {
- aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
- if (!p) {
- return NULL;
- }
- return new CIOStreamWrapper(p);
- }
-
- // ...................................................................
- void Close( IOStream* pFile) {
- if (!pFile) {
- return;
- }
- mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
- delete pFile;
- }
-private:
- aiFileIO* mFileSystem;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Custom LogStream implementation for the C-API
-class LogToCallbackRedirector : public LogStream
-{
-public:
- LogToCallbackRedirector(const aiLogStream& s)
- : stream (s) {
- ai_assert(NULL != s.callback);
- }
-
- ~LogToCallbackRedirector() {
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gLogStreamMutex);
-#endif
- // (HACK) Check whether the 'stream.user' pointer points to a
- // custom LogStream allocated by #aiGetPredefinedLogStream.
- // In this case, we need to delete it, too. Of course, this
- // might cause strange problems, but the chance is quite low.
-
- PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
- gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
-
- if (it != gPredefinedStreams.end()) {
- delete *it;
- gPredefinedStreams.erase(it);
- }
- }
-
- /** @copydoc LogStream::write */
- void write(const char* message) {
- stream.callback(message,stream.user);
- }
-
-private:
- aiLogStream stream;
-};
-
-// ------------------------------------------------------------------------------------------------
-void ReportSceneNotFoundError()
-{
- DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
- "Are you playing fools with us? Don't mix cpp and c API. Thanks.");
-
- assert(false);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the given file and returns its content.
-const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
-{
- return aiImportFileEx(pFile,pFlags,NULL);
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,
- aiFileIO* pFS)
-{
- ai_assert(NULL != pFile);
-
- const aiScene* scene = NULL;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // create an Importer for this file
- Assimp::Importer* imp = new Assimp::Importer();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- // copy the global property lists to the Importer instance
- imp->pimpl->mIntProperties = gIntProperties;
- imp->pimpl->mFloatProperties = gFloatProperties;
- imp->pimpl->mStringProperties = gStringProperties;
-
-#ifdef AI_C_THREADSAFE
- lock.unlock();
-#endif
-
- // setup a custom IO system if necessary
- if (pFS) {
- imp->SetIOHandler( new CIOSystemWrapper (pFS) );
- }
-
- // and have it read the file
- scene = imp->ReadFile( pFile, pFlags);
-
- // if succeeded, place it in the collection of active processes
- if ( scene) {
-#ifdef AI_C_THREADSAFE
- lock.lock();
-#endif
- gActiveImports[scene] = imp;
- }
- else {
- // if failed, extract error code and destroy the import
- gLastErrorString = imp->GetErrorString();
- delete imp;
- }
-
- // return imported data. If the import failed the pointer is NULL anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return scene;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileFromMemory(
- const char* pBuffer,
- unsigned int pLength,
- unsigned int pFlags,
- const char* pHint)
-{
- ai_assert(NULL != pBuffer && 0 != pLength);
-
- const aiScene* scene = NULL;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // create an Importer for this file
- Assimp::Importer* imp = new Assimp::Importer();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- // copy the global property lists to the Importer instance
- imp->pimpl->mIntProperties = gIntProperties;
- imp->pimpl->mFloatProperties = gFloatProperties;
- imp->pimpl->mStringProperties = gStringProperties;
-
-#ifdef AI_C_THREADSAFE
- lock.unlock();
-#endif
-
- // and have it read the file from the memory buffer
- scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
-
- // if succeeded, place it in the collection of active processes
- if ( scene) {
-#ifdef AI_C_THREADSAFE
- lock.lock();
-#endif
- gActiveImports[scene] = imp;
- }
- else {
- // if failed, extract error code and destroy the import
- gLastErrorString = imp->GetErrorString();
- delete imp;
- }
- // return imported data. If the import failed the pointer is NULL anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return scene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Releases all resources associated with the given import process.
-void aiReleaseImport( const aiScene* pScene)
-{
- if (!pScene) {
- return;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
-
- // find the importer associated with this data
- ImporterMap::iterator it = gActiveImports.find( pScene);
- // it should be there... else the user is playing fools with us
- if ( it == gActiveImports.end()) {
- ReportSceneNotFoundError();
- return;
- }
-
- // kill the importer, the data dies with it
- delete it->second;
- gActiveImports.erase( it);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
- unsigned int pFlags)
-{
- const aiScene* sc = NULL;
-
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- // find the importer associated with this data
- ImporterMap::iterator it = gActiveImports.find( pScene);
- // it should be there... else the user is playing fools with us
- if ( it == gActiveImports.end()) {
- ReportSceneNotFoundError();
- return NULL;
- }
-#ifdef AI_C_THREADSAFE
- lock.unlock();
-#endif
- sc = it->second->ApplyPostProcessing(pFlags);
-#ifdef AI_C_THREADSAFE
- lock.lock();
-#endif
- if (!sc) {
- // kill the importer, the data dies with it
- delete it->second;
- gActiveImports.erase( it);
- return NULL;
- }
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return sc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void CallbackToLogRedirector (const char* msg, char* dt)
-{
- ai_assert(NULL != msg && NULL != dt);
- LogStream* s = (LogStream*)dt;
-
- s->write(msg);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
-{
- aiLogStream sout;
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- LogStream* stream = LogStream::createDefaultStream(pStream,file);
- if (!stream) {
- sout.callback = NULL;
- sout.user = NULL;
- }
- else {
- sout.callback = &CallbackToLogRedirector;
- sout.user = (char*)stream;
- }
- gPredefinedStreams.push_back(stream);
- ASSIMP_END_EXCEPTION_REGION(aiLogStream);
- return sout;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gLogStreamMutex);
-#endif
-
- LogStream* lg = new LogToCallbackRedirector(*stream);
- gActiveLogStreams[*stream] = lg;
-
- if (DefaultLogger::isNullLogger()) {
- DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
- }
- DefaultLogger::get()->attachStream(lg);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gLogStreamMutex);
-#endif
- // find the logstream associated with this data
- LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
- // it should be there... else the user is playing fools with us
- if ( it == gActiveLogStreams.end()) {
- return AI_FAILURE;
- }
- DefaultLogger::get()->detatchStream( it->second );
- delete it->second;
-
- gActiveLogStreams.erase( it);
-
- if (gActiveLogStreams.empty()) {
- DefaultLogger::kill();
- }
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiDetachAllLogStreams(void)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gLogStreamMutex);
-#endif
- for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
- DefaultLogger::get()->detatchStream( it->second );
- delete it->second;
- }
- gActiveLogStreams.clear();
- DefaultLogger::kill();
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiEnableVerboseLogging(aiBool d)
-{
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
- }
- gVerboseLogging = d;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the error text of the last failed import process.
-const char* aiGetErrorString()
-{
- return gLastErrorString.c_str();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the error text of the last failed import process.
-aiBool aiIsExtensionSupported(const char* szExtension)
-{
- ai_assert(NULL != szExtension);
- aiBool candoit=AI_FALSE;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
-
- if (!gActiveImports.empty()) {
- return ((*(gActiveImports.begin())).second->IsExtensionSupported( szExtension )) ? AI_TRUE : AI_FALSE;
- }
-
- // fixme: no need to create a temporary Importer instance just for that ..
- Assimp::Importer tmp;
- candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
-
- ASSIMP_END_EXCEPTION_REGION(aiBool);
- return candoit;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all file extensions supported by ASSIMP
-void aiGetExtensionList(aiString* szOut)
-{
- ai_assert(NULL != szOut);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
-
- if (!gActiveImports.empty()) {
- (*(gActiveImports.begin())).second->GetExtensionList(*szOut);
- return;
- }
- // fixme: no need to create a temporary Importer instance just for that ..
- Assimp::Importer tmp;
- tmp.GetExtensionList(*szOut);
-
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the memory requirements for a particular import.
-void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
- C_STRUCT aiMemoryInfo* in)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
-
- // find the importer associated with this data
- ImporterMap::iterator it = gActiveImports.find( pIn);
- // it should be there... else the user is playing fools with us
- if ( it == gActiveImports.end()) {
- ReportSceneNotFoundError();
- return;
- }
- // get memory statistics
-#ifdef AI_C_THREADSAFE
- lock.unlock();
-#endif
- it->second->GetMemoryRequirements(*in);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyInteger
-ASSIMP_API void aiSetImportPropertyInteger(const char* szName, int value)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- SetGenericProperty<int>(gIntProperties,szName,value,NULL);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyFloat
-ASSIMP_API void aiSetImportPropertyFloat(const char* szName, float value)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- SetGenericProperty<float>(gFloatProperties,szName,value,NULL);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyString
-ASSIMP_API void aiSetImportPropertyString(const char* szName,
- const C_STRUCT aiString* st)
-{
- if (!st) {
- return;
- }
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifdef AI_C_THREADSAFE
- boost::mutex::scoped_lock lock(gMutex);
-#endif
- SetGenericProperty<std::string>(gStringProperties,szName,
- std::string( st->data ),NULL);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Rotation matrix to quaternion
-ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
-{
- ai_assert(NULL != quat && NULL != mat);
- *quat = aiQuaternion(*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix decomposition
-ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
- aiQuaternion* rotation,
- aiVector3D* position)
-{
- ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
- mat->Decompose(*scaling,*rotation,*position);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix transpose
-ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
-{
- ai_assert(NULL != mat);
- mat->Transpose();
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
-{
- ai_assert(NULL != mat);
- mat->Transpose();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Vector transformation
-ASSIMP_API void aiTransformVecByMatrix3(C_STRUCT aiVector3D* vec,
- const C_STRUCT aiMatrix3x3* mat)
-{
- ai_assert(NULL != mat && NULL != vec);
- *vec *= (*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiTransformVecByMatrix4(C_STRUCT aiVector3D* vec,
- const C_STRUCT aiMatrix4x4* mat)
-{
- ai_assert(NULL != mat && NULL != vec);
- *vec *= (*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix multiplication
-ASSIMP_API void aiMultiplyMatrix4(
- C_STRUCT aiMatrix4x4* dst,
- const C_STRUCT aiMatrix4x4* src)
-{
- ai_assert(NULL != dst && NULL != src);
- *dst = (*dst) * (*src);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiMultiplyMatrix3(
- C_STRUCT aiMatrix3x3* dst,
- const C_STRUCT aiMatrix3x3* src)
-{
- ai_assert(NULL != dst && NULL != src);
- *dst = (*dst) * (*src);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix identity
-ASSIMP_API void aiIdentityMatrix3(
- C_STRUCT aiMatrix3x3* mat)
-{
- ai_assert(NULL != mat);
- *mat = aiMatrix3x3();
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiIdentityMatrix4(
- C_STRUCT aiMatrix4x4* mat)
-{
- ai_assert(NULL != mat);
- *mat = aiMatrix4x4();
-}
-
-
diff --git a/3rdparty/assimp/code/AssimpPCH.cpp b/3rdparty/assimp/code/AssimpPCH.cpp
deleted file mode 100644
index 5ccfb4ef..00000000
--- a/3rdparty/assimp/code/AssimpPCH.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-
-// Actually just a dummy, used by the compiler to build the precompiled header.
-
-#include "AssimpPCH.h"
-#include "./../include/aiVersion.h"
-
-// --------------------------------------------------------------------------------
-// Legal information string - dont't remove from image!
-static const char* LEGAL_INFORMATION =
-
-"Open Asset Import Library (Assimp).\n"
-"A free C/C++ library to import various 3D file formats into applications\n\n"
-
-"(c) ASSIMP Development Team, 2008-2010\n"
-"License: 3-clause BSD license\n"
-"Website: http://assimp.sourceforge.net\n"
-;
-
-// ------------------------------------------------------------------------------------------------
-// Get legal string
-ASSIMP_API const char* aiGetLegalString () {
- return LEGAL_INFORMATION;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get Assimp minor version
-ASSIMP_API unsigned int aiGetVersionMinor () {
- return 1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get Assimp major version
-ASSIMP_API unsigned int aiGetVersionMajor () {
- return 1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get flags used for compilation
-ASSIMP_API unsigned int aiGetCompileFlags () {
-
- unsigned int flags = 0;
-
-#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
- flags |= ASSIMP_CFLAGS_NOBOOST;
-#endif
-#ifdef ASSIMP_BUILD_SINGLETHREADED
- flags |= ASSIMP_CFLAGS_SINGLETHREADED;
-#endif
-#ifdef ASSIMP_BUILD_DEBUG
- flags |= ASSIMP_CFLAGS_DEBUG;
-#endif
-#ifdef ASSIMP_BUILD_DLL_EXPORT
- flags |= ASSIMP_CFLAGS_SHARED;
-#endif
-#ifdef _STLPORT_VERSION
- flags |= ASSIMP_CFLAGS_STLPORT;
-#endif
-
- return flags;
-}
-
-// include current build revision, which is even updated from time to time -- :-)
-#include "../revision.h"
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API unsigned int aiGetVersionRevision ()
-{
- return SVNRevision;
-}
-
diff --git a/3rdparty/assimp/code/AssimpPCH.h b/3rdparty/assimp/code/AssimpPCH.h
deleted file mode 100644
index 779f681c..00000000
--- a/3rdparty/assimp/code/AssimpPCH.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file AssimpPCH.h
- * PCH master include. Every unit in Assimp has to include it.
- */
-
-#ifndef ASSIMP_PCH_INCLUDED
-#define ASSIMP_PCH_INCLUDED
-#define ASSIMP_INTERNAL_BUILD
-
-// ----------------------------------------------------------------------------------------
-/* General compile config taken from aiDefines.h. It is important that the user compiles
- * using exactly the same settings in aiDefines.h. Settings in AssimpPCH.h may differ,
- * they won't affect the public API.
- */
-#include "../include/aiDefines.h"
-
-/* Include our stdint.h replacement header for MSVC, take the global header for gcc/mingw
- */
-#ifdef _MSC_VER
-# include "pstdint.h"
-#else
-# include <stdint.h>
-#endif
-
-/* Undefine the min/max macros defined by some platform headers (namely Windows.h) to
- * avoid obvious conflicts with std::min() and std::max().
- */
-#undef min
-#undef max
-
-/* Concatenate two tokens after evaluating them
- */
-#define _AI_CONCAT(a,b) a ## b
-#define AI_CONCAT(a,b) _AI_CONCAT(a,b)
-
-/* Helper macro to set a pointer to NULL in debug builds
- */
-#if (defined _DEBUG)
-# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
-#else
-# define AI_DEBUG_INVALIDATE_PTR(x)
-#endif
-
-/* Beginning with MSVC8 some C string manipulation functions are mapped to their _safe_
- * counterparts (e.g. _itoa_s). This avoids a lot of trouble with deprecation warnings.
- */
-#if _MSC_VER >= 1400 && !(defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
-# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
-#endif
-
-/* size_t to unsigned int, possible loss of data. The compiler is right with his warning
- * but this loss of data won't be a problem for us. So shut up, little boy.
- */
-#ifdef _MSC_VER
-# pragma warning (disable : 4267)
-#endif
-
-// ----------------------------------------------------------------------------------------
-/* Actually that's not required for MSVC. It is included somewhere in the deeper parts of
- * the MSVC STL but it's necessary for proper build with STLport.
- */
-#include <ctype.h>
-
-// Runtime/STL headers
-#include <vector>
-#include <list>
-#include <map>
-#include <set>
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <cassert>
-#include <stack>
-#include <queue>
-#include <iostream>
-#include <algorithm>
-#include <numeric>
-#include <new>
-#include <cstdio>
-
-// Boost headers
-#include <boost/pointer_cast.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/shared_array.hpp>
-//#include <boost/make_shared.hpp>
-#include <boost/format.hpp>
-#include <boost/foreach.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/lexical_cast.hpp>
-
-// Public ASSIMP headers
-#include "../include/DefaultLogger.h"
-#include "../include/IOStream.h"
-#include "../include/IOSystem.h"
-#include "../include/aiScene.h"
-#include "../include/aiPostProcess.h"
-#include "../include/assimp.hpp"
-
-// Internal utility headers
-#include "BaseImporter.h"
-#include "MaterialSystem.h"
-#include "StringComparison.h"
-#include "StreamReader.h"
-#include "qnan.h"
-
-
-#endif // !! ASSIMP_PCH_INCLUDED
diff --git a/3rdparty/assimp/code/B3DImporter.cpp b/3rdparty/assimp/code/B3DImporter.cpp
deleted file mode 100644
index 0609c275..00000000
--- a/3rdparty/assimp/code/B3DImporter.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file B3DImporter.cpp
- * @brief Implementation of the b3d importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-
-// internal headers
-#include "B3DImporter.h"
-#include "TextureTransform.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-using namespace std;
-
-// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings
-#ifdef _MSC_VER
-# pragma warning (disable: 4018)
-#endif
-
-//#define DEBUG_B3D
-
-// ------------------------------------------------------------------------------------------------
-bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /* pIOHandler */, bool /* checkSig */) const{
-
- size_t pos=pFile.find_last_of( '.' );
- if ( pos==string::npos ) return false;
-
- string ext=pFile.substr( pos+1 );
- if ( ext.size()!=3 ) return false;
-
- return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::GetExtensionList( std::set<std::string>& extensions ){
- extensions.insert("b3d");
-}
-
-#ifdef DEBUG_B3D
- extern "C"{ void _stdcall AllocConsole(); }
-#endif
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
-
-#ifdef DEBUG_B3D
- AllocConsole();
- freopen( "conin$","r",stdin );
- freopen( "conout$","w",stdout );
- freopen( "conout$","w",stderr );
- cout<<"Hello world from the B3DImporter!"<<endl;
-#endif
-
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open B3D file " + pFile + ".");
-
- // check whether the .b3d file is large enough to contain
- // at least one chunk.
- size_t fileSize = file->FileSize();
- if ( fileSize<8 ) throw DeadlyImportError( "B3D File is too small.");
-
- _pos=0;
- _buf.resize( fileSize );
- file->Read( &_buf[0],1,fileSize );
- _stack.clear();
-
- ReadBB3D( pScene );
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::Oops(){
- throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::Fail( string str ){
-#ifdef DEBUG_B3D
- cout<<"Error in B3D file data: "<<str<<endl;
-#endif
- throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str );
-}
-
-// ------------------------------------------------------------------------------------------------
-int B3DImporter::ReadByte(){
- if ( _pos<_buf.size() ) return _buf[_pos++];
- Fail( "EOF" );
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-int B3DImporter::ReadInt(){
- if ( _pos+4<=_buf.size() ){
- int n=*(int*)&_buf[_pos];
- _pos+=4;
- return n;
- }
- Fail( "EOF" );
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-float B3DImporter::ReadFloat(){
- if ( _pos+4<=_buf.size() ){
- float n=*(float*)&_buf[_pos];
- _pos+=4;
- return n;
- }
- Fail( "EOF" );
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector2D B3DImporter::ReadVec2(){
- float x=ReadFloat();
- float y=ReadFloat();
- return aiVector2D( x,y );
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector3D B3DImporter::ReadVec3(){
- float x=ReadFloat();
- float y=ReadFloat();
- float z=ReadFloat();
- return aiVector3D( x,y,z );
-}
-
-// ------------------------------------------------------------------------------------------------
-aiQuaternion B3DImporter::ReadQuat(){
- // (aramis_acg) Fix to adapt the loader to changed quat orientation
- float w=-ReadFloat();
- float x=ReadFloat();
- float y=ReadFloat();
- float z=ReadFloat();
- return aiQuaternion( w,x,y,z );
-}
-
-// ------------------------------------------------------------------------------------------------
-string B3DImporter::ReadString(){
- string str;
- while ( _pos<_buf.size() ){
- char c=(char)ReadByte();
- if ( !c ) return str;
- str+=c;
- }
- Fail( "EOF" );
- return string();
-}
-
-// ------------------------------------------------------------------------------------------------
-string B3DImporter::ReadChunk(){
- string tag;
- for ( int i=0;i<4;++i ){
- tag+=char( ReadByte() );
- }
-#ifdef DEBUG_B3D
-// cout<<"ReadChunk:"<<tag<<endl;
-#endif
- unsigned sz=(unsigned)ReadInt();
- _stack.push_back( _pos+sz );
- return tag;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ExitChunk(){
- _pos=_stack.back();
- _stack.pop_back();
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned B3DImporter::ChunkSize(){
- return _stack.back()-_pos;
-}
-// ------------------------------------------------------------------------------------------------
-
-template<class T>
-T *B3DImporter::to_array( const vector<T> &v ){
- if ( !v.size() ) return 0;
- T *p=new T[v.size()];
- for ( size_t i=0;i<v.size();++i ){
- p[i]=v[i];
- }
- return p;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadTEXS(){
- while ( ChunkSize() ){
- string name=ReadString();
- /*int flags=*/ReadInt();
- /*int blend=*/ReadInt();
- /*aiVector2D pos=*/ReadVec2();
- /*aiVector2D scale=*/ReadVec2();
- /*float rot=*/ReadFloat();
-
- _textures.push_back( name );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBRUS(){
- int n_texs=ReadInt();
- if ( n_texs<0 || n_texs>8 ){
- Fail( "Bad texture count" );
- }
- while ( ChunkSize() ){
- string name=ReadString();
- aiVector3D color=ReadVec3();
- float alpha=ReadFloat();
- float shiny=ReadFloat();
- /*int blend=**/ReadInt();
- int fx=ReadInt();
-
- MaterialHelper *mat=new MaterialHelper;
- _materials.push_back( mat );
-
- // Name
- aiString ainame( name );
- mat->AddProperty( &ainame,AI_MATKEY_NAME );
-
- // Diffuse color
- mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );
-
- // Opacity
- mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );
-
- // Specular color
- aiColor3D speccolor( shiny,shiny,shiny );
- mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR );
-
- // Specular power
- float specpow=shiny*128;
- mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS );
-
- // Double sided
- if ( fx & 0x10 ){
- int i=1;
- mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED );
- }
-
- //Textures
- for ( int i=0;i<n_texs;++i ){
- int texid=ReadInt();
- if ( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){
- Fail( "Bad texture id" );
- }
- if ( i==0 && texid>=0 ){
- aiString texname( _textures[texid] );
- mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadVRTS(){
- _vflags=ReadInt();
- _tcsets=ReadInt();
- _tcsize=ReadInt();
- if ( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
- Fail( "Bad texcoord data" );
- }
-
- int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
- int n_verts=ChunkSize()/sz;
-
- int v0=_vertices.size();
- _vertices.resize( v0+n_verts );
-
- for ( int i=0;i<n_verts;++i ){
- Vertex &v=_vertices[v0+i];
-
- memset( v.bones,0,sizeof(v.bones) );
- memset( v.weights,0,sizeof(v.weights) );
-
- v.vertex=ReadVec3();
-
- if ( _vflags & 1 ) v.normal=ReadVec3();
-
- if ( _vflags & 2 ) ReadQuat(); //skip v 4bytes...
-
- for ( int i=0;i<_tcsets;++i ){
- float t[4]={0,0,0,0};
- for ( int j=0;j<_tcsize;++j ){
- t[j]=ReadFloat();
- }
- t[1]=1-t[1];
- if ( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadTRIS( int v0 ){
- int matid=ReadInt();
- if ( matid==-1 ){
- matid=0;
- }else if ( matid<0 || matid>=(int)_materials.size() ){
-#ifdef DEBUG_B3D
- cout<<"material id="<<matid<<endl;
-#endif
- Fail( "Bad material id" );
- }
-
- aiMesh *mesh=new aiMesh;
- _meshes.push_back( mesh );
-
- mesh->mMaterialIndex=matid;
- mesh->mNumFaces=0;
- mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;
-
- int n_tris=ChunkSize()/12;
- aiFace *face=mesh->mFaces=new aiFace[n_tris];
-
- for ( int i=0;i<n_tris;++i ){
- int i0=ReadInt()+v0;
- int i1=ReadInt()+v0;
- int i2=ReadInt()+v0;
- if ( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){
-#ifdef DEBUG_B3D
- cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
-#endif
- Fail( "Bad triangle index" );
- continue;
- }
- face->mNumIndices=3;
- face->mIndices=new unsigned[3];
- face->mIndices[0]=i0;
- face->mIndices[1]=i1;
- face->mIndices[2]=i2;
- ++mesh->mNumFaces;
- ++face;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadMESH(){
- /*int matid=*/ReadInt();
-
- int v0=_vertices.size();
-
- while ( ChunkSize() ){
- string t=ReadChunk();
- if ( t=="VRTS" ){
- ReadVRTS();
- }else if ( t=="TRIS" ){
- ReadTRIS( v0 );
- }
- ExitChunk();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBONE( int id ){
- while ( ChunkSize() ){
- int vertex=ReadInt();
- float weight=ReadFloat();
- if ( vertex<0 || vertex>=(int)_vertices.size() ){
- Fail( "Bad vertex index" );
- }
-
- Vertex &v=_vertices[vertex];
- int i;
- for ( i=0;i<4;++i ){
- if ( !v.weights[i] ){
- v.bones[i]=id;
- v.weights[i]=weight;
- break;
- }
- }
-#ifdef DEBUG_B3D
- if ( i==4 ){
- cout<<"Too many bone weights"<<endl;
- }
-#endif
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
- vector<aiVectorKey> trans,scale;
- vector<aiQuatKey> rot;
- int flags=ReadInt();
- while ( ChunkSize() ){
- int frame=ReadInt();
- if ( flags & 1 ){
- trans.push_back( aiVectorKey( frame,ReadVec3() ) );
- }
- if ( flags & 2 ){
- scale.push_back( aiVectorKey( frame,ReadVec3() ) );
- }
- if ( flags & 4 ){
- rot.push_back( aiQuatKey( frame,ReadQuat() ) );
- }
- }
-
- if ( flags & 1 ){
- nodeAnim->mNumPositionKeys=trans.size();
- nodeAnim->mPositionKeys=to_array( trans );
- }
-
- if ( flags & 2 ){
- nodeAnim->mNumScalingKeys=scale.size();
- nodeAnim->mScalingKeys=to_array( scale );
- }
-
- if ( flags & 4 ){
- nodeAnim->mNumRotationKeys=rot.size();
- nodeAnim->mRotationKeys=to_array( rot );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadANIM(){
- /*int flags=*/ReadInt();
- int frames=ReadInt();
- float fps=ReadFloat();
-
- aiAnimation *anim=new aiAnimation;
- _animations.push_back( anim );
-
- anim->mDuration=frames;
- anim->mTicksPerSecond=fps;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode *B3DImporter::ReadNODE( aiNode *parent ){
-
- string name=ReadString();
- aiVector3D t=ReadVec3();
- aiVector3D s=ReadVec3();
- aiQuaternion r=ReadQuat();
-
- aiMatrix4x4 trans,scale,rot;
-
- aiMatrix4x4::Translation( t,trans );
- aiMatrix4x4::Scaling( s,scale );
- rot=aiMatrix4x4( r.GetMatrix() );
-
- aiMatrix4x4 tform=trans * rot * scale;
-
- int nodeid=_nodes.size();
-
- aiNode *node=new aiNode( name );
- _nodes.push_back( node );
-
- node->mParent=parent;
- node->mTransformation=tform;
-
- aiNodeAnim *nodeAnim=0;
- vector<unsigned> meshes;
- vector<aiNode*> children;
-
- while ( ChunkSize() ){
- string t=ReadChunk();
- if ( t=="MESH" ){
- int n=_meshes.size();
- ReadMESH();
- for ( int i=n;i<(int)_meshes.size();++i ){
- meshes.push_back( i );
- }
- }else if ( t=="BONE" ){
- ReadBONE( nodeid );
- }else if ( t=="ANIM" ){
- ReadANIM();
- }else if ( t=="KEYS" ){
- if ( !nodeAnim ){
- nodeAnim=new aiNodeAnim;
- _nodeAnims.push_back( nodeAnim );
- nodeAnim->mNodeName=node->mName;
- }
- ReadKEYS( nodeAnim );
- }else if ( t=="NODE" ){
- aiNode *child=ReadNODE( node );
- children.push_back( child );
- }
- ExitChunk();
- }
-
- node->mNumMeshes=meshes.size();
- node->mMeshes=to_array( meshes );
-
- node->mNumChildren=children.size();
- node->mChildren=to_array( children );
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBB3D( aiScene *scene ){
-
- _textures.clear();
- _materials.size();
-
- _vertices.clear();
- _meshes.clear();
-
- _nodes.clear();
- _nodeAnims.clear();
- _animations.clear();
-
- string t=ReadChunk();
- if ( t=="BB3D" ){
- int version=ReadInt();
-
- if (!DefaultLogger::isNullLogger()) {
- char dmp[128];
- sprintf(dmp,"B3D file format version: %i",version);
- DefaultLogger::get()->info(dmp);
- }
-
- while ( ChunkSize() ){
- string t=ReadChunk();
- if ( t=="TEXS" ){
- ReadTEXS();
- }else if ( t=="BRUS" ){
- ReadBRUS();
- }else if ( t=="NODE" ){
- ReadNODE( 0 );
- }
- ExitChunk();
- }
- }
- ExitChunk();
-
- if ( !_nodes.size() ) Fail( "No nodes" );
-
- if ( !_meshes.size() ) Fail( "No meshes" );
-
- //Fix nodes/meshes/bones
- for (size_t i=0;i<_nodes.size();++i ){
- aiNode *node=_nodes[i];
-
- for ( size_t j=0;j<node->mNumMeshes;++j ){
- aiMesh *mesh=_meshes[node->mMeshes[j]];
-
- int n_tris=mesh->mNumFaces;
- int n_verts=mesh->mNumVertices=n_tris * 3;
-
- aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
- if ( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
- if ( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];
-
- aiFace *face=mesh->mFaces;
-
- vector< vector<aiVertexWeight> > vweights( _nodes.size() );
-
- for ( int i=0;i<n_verts;i+=3 ){
- for ( int j=0;j<3;++j ){
- Vertex &v=_vertices[face->mIndices[j]];
-
- *mv++=v.vertex;
- if ( mn ) *mn++=v.normal;
- if ( mc ) *mc++=v.texcoords;
-
- face->mIndices[j]=i+j;
-
- for ( int k=0;k<4;++k ){
- if ( !v.weights[k] ) break;
-
- int bone=v.bones[k];
- float weight=v.weights[k];
-
- vweights[bone].push_back( aiVertexWeight(i+j,weight) );
- }
- }
- ++face;
- }
-
- vector<aiBone*> bones;
- for (size_t i=0;i<vweights.size();++i ){
- vector<aiVertexWeight> &weights=vweights[i];
- if ( !weights.size() ) continue;
-
- aiBone *bone=new aiBone;
- bones.push_back( bone );
-
- aiNode *bnode=_nodes[i];
-
- bone->mName=bnode->mName;
- bone->mNumWeights=weights.size();
- bone->mWeights=to_array( weights );
-
- aiMatrix4x4 mat=bnode->mTransformation;
- while ( bnode->mParent ){
- bnode=bnode->mParent;
- mat=bnode->mTransformation * mat;
- }
- bone->mOffsetMatrix=mat.Inverse();
- }
- mesh->mNumBones=bones.size();
- mesh->mBones=to_array( bones );
- }
- }
-
- //nodes
- scene->mRootNode=_nodes[0];
-
- //material
- if ( !_materials.size() ){
- _materials.push_back( new MaterialHelper );
- }
- scene->mNumMaterials=_materials.size();
- scene->mMaterials=to_array( _materials );
-
- //meshes
- scene->mNumMeshes=_meshes.size();
- scene->mMeshes=to_array( _meshes );
-
- //animations
- if ( _animations.size()==1 && _nodeAnims.size() ){
-
- aiAnimation *anim=_animations.back();
- anim->mNumChannels=_nodeAnims.size();
- anim->mChannels=to_array( _nodeAnims );
-
- scene->mNumAnimations=_animations.size();
- scene->mAnimations=to_array( _animations );
- }
-
- // convert to RH
- MakeLeftHandedProcess makeleft;
- makeleft.Execute( scene );
-
- FlipWindingOrderProcess flip;
- flip.Execute( scene );
-}
-
-#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
diff --git a/3rdparty/assimp/code/B3DImporter.h b/3rdparty/assimp/code/B3DImporter.h
deleted file mode 100644
index 302e33dd..00000000
--- a/3rdparty/assimp/code/B3DImporter.h
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Definition of the .b3d importer class. */
-
-#ifndef AI_B3DIMPORTER_H_INC
-#define AI_B3DIMPORTER_H_INC
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiMaterial.h"
-
-#include <string>
-#include <vector>
-
-namespace Assimp{
-
-class B3DImporter : public BaseImporter{
-public:
-
- virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-protected:
-
- virtual void GetExtensionList(std::set<std::string>& extensions);
- virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
-private:
-
- int ReadByte();
- int ReadInt();
- float ReadFloat();
- aiVector2D ReadVec2();
- aiVector3D ReadVec3();
- aiQuaternion ReadQuat();
- std::string ReadString();
- std::string ReadChunk();
- void ExitChunk();
- unsigned ChunkSize();
-
- template<class T>
- T *to_array( const std::vector<T> &v );
-
- struct Vertex{
- aiVector3D vertex;
- aiVector3D normal;
- aiVector3D texcoords;
- unsigned char bones[4];
- float weights[4];
- };
-
- void Oops();
- void Fail( std::string str );
-
- void ReadTEXS();
- void ReadBRUS();
-
- void ReadVRTS();
- void ReadTRIS( int v0 );
- void ReadMESH();
- void ReadBONE( int id );
- void ReadKEYS( aiNodeAnim *nodeAnim );
- void ReadANIM();
-
- aiNode *ReadNODE( aiNode *parent );
-
- void ReadBB3D( aiScene *scene );
-
- unsigned _pos;
-// unsigned _size;
- std::vector<unsigned char> _buf;
- std::vector<unsigned> _stack;
-
- std::vector<std::string> _textures;
- std::vector<aiMaterial*> _materials;
-
- int _vflags,_tcsets,_tcsize;
- std::vector<Vertex> _vertices;
-
- std::vector<aiNode*> _nodes;
- std::vector<aiMesh*> _meshes;
- std::vector<aiNodeAnim*> _nodeAnims;
- std::vector<aiAnimation*> _animations;
-};
-
-}
-
-#endif
diff --git a/3rdparty/assimp/code/BVHLoader.cpp b/3rdparty/assimp/code/BVHLoader.cpp
deleted file mode 100644
index 80171467..00000000
--- a/3rdparty/assimp/code/BVHLoader.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/** Implementation of the BVH loader */
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
-
-#include "BVHLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BVHLoader::BVHLoader()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BVHLoader::~BVHLoader()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if ( extension == "bvh")
- return true;
-
- if ((!extension.length() || cs) && pIOHandler) {
- const char* tokens[] = {"HIERARCHY"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- mFileName = pFile;
-
- // read file into memory
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- size_t fileSize = file->FileSize();
- if ( fileSize == 0)
- throw DeadlyImportError( "File is too small.");
-
- mBuffer.resize( fileSize);
- file->Read( &mBuffer.front(), 1, fileSize);
-
- // start reading
- mReader = mBuffer.begin();
- mLine = 1;
- ReadStructure( pScene);
-
- // build a dummy mesh for the skeleton so that we see something at least
- SkeletonMeshBuilder meshBuilder( pScene);
-
- // construct an animation from all the motion data we read
- CreateAnimation( pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the file
-void BVHLoader::ReadStructure( aiScene* pScene)
-{
- // first comes hierarchy
- std::string header = GetNextToken();
- if ( header != "HIERARCHY")
- ThrowException( "Expected header string \"HIERARCHY\".");
- ReadHierarchy( pScene);
-
- // then comes the motion data
- std::string motion = GetNextToken();
- if ( motion != "MOTION")
- ThrowException( "Expected beginning of motion data \"MOTION\".");
- ReadMotion( pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the hierarchy
-void BVHLoader::ReadHierarchy( aiScene* pScene)
-{
- std::string root = GetNextToken();
- if ( root != "ROOT")
- ThrowException( "Expected root node \"ROOT\".");
-
- // Go read the hierarchy from here
- pScene->mRootNode = ReadNode();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a node and recursively its childs and returns the created node;
-aiNode* BVHLoader::ReadNode()
-{
- // first token is name
- std::string nodeName = GetNextToken();
- if ( nodeName.empty() || nodeName == "{")
- ThrowException( boost::str( boost::format( "Expected node name, but found \"%s\".") % nodeName));
-
- // then an opening brace should follow
- std::string openBrace = GetNextToken();
- if ( openBrace != "{")
- ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
-
- // Create a node
- aiNode* node = new aiNode( nodeName);
- std::vector<aiNode*> childNodes;
-
- // and create an bone entry for it
- mNodes.push_back( Node( node));
- Node& internNode = mNodes.back();
-
- // now read the node's contents
- while ( 1)
- {
- std::string token = GetNextToken();
-
- // node offset to parent node
- if ( token == "OFFSET")
- ReadNodeOffset( node);
- else if ( token == "CHANNELS")
- ReadNodeChannels( internNode);
- else if ( token == "JOINT")
- {
- // child node follows
- aiNode* child = ReadNode();
- child->mParent = node;
- childNodes.push_back( child);
- }
- else if ( token == "End")
- {
- // The real symbol is "End Site". Second part comes in a separate token
- std::string siteToken = GetNextToken();
- if ( siteToken != "Site")
- ThrowException( boost::str( boost::format( "Expected \"End Site\" keyword, but found \"%s %s\".") % token % siteToken));
-
- aiNode* child = ReadEndSite( nodeName);
- child->mParent = node;
- childNodes.push_back( child);
- }
- else if ( token == "}")
- {
- // we're done with that part of the hierarchy
- break;
- } else
- {
- // everything else is a parse error
- ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
- }
- }
-
- // add the child nodes if there are any
- if ( childNodes.size() > 0)
- {
- node->mNumChildren = childNodes.size();
- node->mChildren = new aiNode*[node->mNumChildren];
- std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
- }
-
- // and return the sub-hierarchy we built here
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an end node and returns the created node.
-aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
-{
- // check opening brace
- std::string openBrace = GetNextToken();
- if ( openBrace != "{")
- ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
-
- // Create a node
- aiNode* node = new aiNode( "EndSite_" + pParentName);
-
- // now read the node's contents. Only possible entry is "OFFSET"
- while ( 1)
- {
- std::string token = GetNextToken();
-
- // end node's offset
- if ( token == "OFFSET")
- {
- ReadNodeOffset( node);
- }
- else if ( token == "}")
- {
- // we're done with the end node
- break;
- } else
- {
- // everything else is a parse error
- ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
- }
- }
-
- // and return the sub-hierarchy we built here
- return node;
-}
-// ------------------------------------------------------------------------------------------------
-// Reads a node offset for the given node
-void BVHLoader::ReadNodeOffset( aiNode* pNode)
-{
- // Offset consists of three floats to read
- aiVector3D offset;
- offset.x = GetNextTokenAsFloat();
- offset.y = GetNextTokenAsFloat();
- offset.z = GetNextTokenAsFloat();
-
- // build a transformation matrix from it
- pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
- 0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the animation channels for the given node
-void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
-{
- // number of channels. Use the float reader because we're lazy
- float numChannelsFloat = GetNextTokenAsFloat();
- unsigned int numChannels = (unsigned int) numChannelsFloat;
-
- for ( unsigned int a = 0; a < numChannels; a++)
- {
- std::string channelToken = GetNextToken();
-
- if ( channelToken == "Xposition")
- pNode.mChannels.push_back( Channel_PositionX);
- else if ( channelToken == "Yposition")
- pNode.mChannels.push_back( Channel_PositionY);
- else if ( channelToken == "Zposition")
- pNode.mChannels.push_back( Channel_PositionZ);
- else if ( channelToken == "Xrotation")
- pNode.mChannels.push_back( Channel_RotationX);
- else if ( channelToken == "Yrotation")
- pNode.mChannels.push_back( Channel_RotationY);
- else if ( channelToken == "Zrotation")
- pNode.mChannels.push_back( Channel_RotationZ);
- else
- ThrowException( boost::str( boost::format( "Invalid channel specifier \"%s\".") % channelToken));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the motion data
-void BVHLoader::ReadMotion( aiScene* /* pScene */)
-{
- // Read number of frames
- std::string tokenFrames = GetNextToken();
- if ( tokenFrames != "Frames:")
- ThrowException( boost::str( boost::format( "Expected frame count \"Frames:\", but found \"%s\".") % tokenFrames));
-
- float numFramesFloat = GetNextTokenAsFloat();
- mAnimNumFrames = (unsigned int) numFramesFloat;
-
- // Read frame duration
- std::string tokenDuration1 = GetNextToken();
- std::string tokenDuration2 = GetNextToken();
- if ( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
- ThrowException( boost::str( boost::format( "Expected frame duration \"Frame Time:\", but found \"%s %s\".") % tokenDuration1 % tokenDuration2));
-
- mAnimTickDuration = GetNextTokenAsFloat();
-
- // resize value vectors for each node
- for ( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
- it->mChannelValues.reserve( it->mChannels.size() * mAnimNumFrames);
-
- // now read all the data and store it in the corresponding node's value vector
- for ( unsigned int frame = 0; frame < mAnimNumFrames; ++frame)
- {
- // on each line read the values for all nodes
- for ( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
- {
- // get as many values as the node has channels
- for ( unsigned int c = 0; c < it->mChannels.size(); ++c)
- it->mChannelValues.push_back( GetNextTokenAsFloat());
- }
-
- // after one frame worth of values for all nodes there should be a newline, but we better don't rely on it
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Retrieves the next token
-std::string BVHLoader::GetNextToken()
-{
- // skip any preceeding whitespace
- while ( mReader != mBuffer.end())
- {
- if ( !isspace( *mReader))
- break;
-
- // count lines
- if ( *mReader == '\n')
- mLine++;
-
- ++mReader;
- }
-
- // collect all chars till the next whitespace. BVH is easy in respect to that.
- std::string token;
- while ( mReader != mBuffer.end())
- {
- if ( isspace( *mReader))
- break;
-
- token.push_back( *mReader);
- ++mReader;
-
- // little extra logic to make sure braces are counted correctly
- if ( token == "{" || token == "}")
- break;
- }
-
- // empty token means end of file, which is just fine
- return token;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the next token as a float
-float BVHLoader::GetNextTokenAsFloat()
-{
- std::string token = GetNextToken();
- if ( token.empty())
- ThrowException( "Unexpected end of file while trying to read a float");
-
- // check if the float is valid by testing if the atof() function consumed every char of the token
- const char* ctoken = token.c_str();
- float result = 0.0f;
- ctoken = fast_atof_move( ctoken, result);
-
- if ( ctoken != token.c_str() + token.length())
- ThrowException( boost::str( boost::format( "Expected a floating point number, but found \"%s\".") % token));
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Aborts the file reading with an exception
-void BVHLoader::ThrowException( const std::string& pError)
-{
- throw DeadlyImportError( boost::str( boost::format( "%s:%d - %s") % mFileName % mLine % pError));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs an animation for the motion data and stores it in the given scene
-void BVHLoader::CreateAnimation( aiScene* pScene)
-{
- // create the animation
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- aiAnimation* anim = new aiAnimation;
- pScene->mAnimations[0] = anim;
-
- // put down the basic parameters
- anim->mName.Set( "Motion");
- anim->mTicksPerSecond = 1.0 / double( mAnimTickDuration);
- anim->mDuration = double( mAnimNumFrames - 1);
-
- // now generate the tracks for all nodes
- anim->mNumChannels = mNodes.size();
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
-
- // FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
- for (unsigned int i = 0; i < anim->mNumChannels;++i)
- anim->mChannels[i] = NULL;
-
- for ( unsigned int a = 0; a < anim->mNumChannels; a++)
- {
- const Node& node = mNodes[a];
- const std::string nodeName = std::string( node.mNode->mName.data );
- aiNodeAnim* nodeAnim = new aiNodeAnim;
- anim->mChannels[a] = nodeAnim;
- nodeAnim->mNodeName.Set( nodeName);
-
- // translational part, if given
- if ( node.mChannels.size() == 6)
- {
- nodeAnim->mNumPositionKeys = mAnimNumFrames;
- nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames];
- aiVectorKey* poskey = nodeAnim->mPositionKeys;
- for ( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
- {
- poskey->mTime = double( fr);
-
- // Now compute all translations in the right order
- for ( unsigned int channel = 0; channel < 3; ++channel)
- {
- switch( node.mChannels[channel])
- {
- case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
- }
- }
- ++poskey;
- }
- } else
- {
- // if no translation part is given, put a default sequence
- aiVector3D nodePos( node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4);
- nodeAnim->mNumPositionKeys = 1;
- nodeAnim->mPositionKeys = new aiVectorKey[1];
- nodeAnim->mPositionKeys[0].mTime = 0.0;
- nodeAnim->mPositionKeys[0].mValue = nodePos;
- }
-
- // rotation part. Always present. First find value offsets
- {
- unsigned int rotOffset = 0;
- if ( node.mChannels.size() == 6)
- {
- // Offset all further calculations
- rotOffset = 3;
- }
-
- // Then create the number of rotation keys
- nodeAnim->mNumRotationKeys = mAnimNumFrames;
- nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames];
- aiQuatKey* rotkey = nodeAnim->mRotationKeys;
- for ( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
- {
- aiMatrix4x4 temp;
- aiMatrix3x3 rotMatrix;
-
- for ( unsigned int channel = 0; channel < 3; ++channel)
- {
- // translate ZXY euler angels into a quaternion
- const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
-
- // Compute rotation transformations in the right order
- switch (node.mChannels[rotOffset+channel])
- {
- case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
- }
- }
-
- rotkey->mTime = double( fr);
- rotkey->mValue = aiQuaternion( rotMatrix);
- ++rotkey;
- }
- }
-
- // scaling part. Always just a default track
- {
- nodeAnim->mNumScalingKeys = 1;
- nodeAnim->mScalingKeys = new aiVectorKey[1];
- nodeAnim->mScalingKeys[0].mTime = 0.0;
- nodeAnim->mScalingKeys[0].mValue.Set( 1.0f, 1.0f, 1.0f);
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
diff --git a/3rdparty/assimp/code/BVHLoader.h b/3rdparty/assimp/code/BVHLoader.h
deleted file mode 100644
index dce8f5f7..00000000
--- a/3rdparty/assimp/code/BVHLoader.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/** Defines the BHV motion capturing loader class */
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BVHLoader.h
- * @brief Biovision BVH import
- */
-
-#ifndef AI_BVHLOADER_H_INC
-#define AI_BVHLOADER_H_INC
-
-#include "BaseImporter.h"
-
-namespace Assimp
-{
-
-// --------------------------------------------------------------------------------
-/** Loader class to read Motion Capturing data from a .bvh file.
- *
- * This format only contains a hierarchy of joints and a series of keyframes for
- * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
- * inside the loader just to be able to see something.
-*/
-class BVHLoader : public BaseImporter
-{
- friend class Importer;
-
- /** Possible animation channels for which the motion data holds the values */
- enum ChannelType
- {
- Channel_PositionX,
- Channel_PositionY,
- Channel_PositionZ,
- Channel_RotationX,
- Channel_RotationY,
- Channel_RotationZ
- };
-
- /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
- struct Node
- {
- const aiNode* mNode;
- std::vector<ChannelType> mChannels;
- std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
-
- Node() { }
- Node( const aiNode* pNode) : mNode( pNode) { }
- };
-
-protected:
- /** Constructor to be privately used by Importer */
- BVHLoader();
-
- /** Destructor, private as well */
- ~BVHLoader();
-
-public:
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
-
-protected:
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions)
- {
- extensions.insert("bvh");
- }
-
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
-protected:
- /** Reads the file */
- void ReadStructure( aiScene* pScene);
-
- /** Reads the hierarchy */
- void ReadHierarchy( aiScene* pScene);
-
- /** Reads a node and recursively its childs and returns the created node. */
- aiNode* ReadNode();
-
- /** Reads an end node and returns the created node. */
- aiNode* ReadEndSite( const std::string& pParentName);
-
- /** Reads a node offset for the given node */
- void ReadNodeOffset( aiNode* pNode);
-
- /** Reads the animation channels into the given node */
- void ReadNodeChannels( BVHLoader::Node& pNode);
-
- /** Reads the motion data */
- void ReadMotion( aiScene* pScene);
-
- /** Retrieves the next token */
- std::string GetNextToken();
-
- /** Reads the next token as a float */
- float GetNextTokenAsFloat();
-
- /** Aborts the file reading with an exception */
- void ThrowException( const std::string& pError);
-
- /** Constructs an animation for the motion data and stores it in the given scene */
- void CreateAnimation( aiScene* pScene);
-
-protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** Buffer to hold the loaded file */
- std::vector<char> mBuffer;
-
- /** Next char to read from the buffer */
- std::vector<char>::const_iterator mReader;
-
- /** Current line, for error messages */
- unsigned int mLine;
-
- /** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
- * Also contain the motion data for the node's channels
- */
- std::vector<Node> mNodes;
-
- /** basic Animation parameters */
- float mAnimTickDuration;
- unsigned int mAnimNumFrames;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_BVHLOADER_H_INC
diff --git a/3rdparty/assimp/code/BaseImporter.cpp b/3rdparty/assimp/code/BaseImporter.cpp
deleted file mode 100644
index cd2de111..00000000
--- a/3rdparty/assimp/code/BaseImporter.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file BaseImporter.cpp
- * @brief Implementation of BaseImporter
- */
-
-#include "AssimpPCH.h"
-#include "BaseImporter.h"
-#include "FileSystemFilter.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BaseImporter::BaseImporter()
-: progress()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BaseImporter::~BaseImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file and returns the imported data.
-aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
-{
- progress = pImp->GetProgressHandler();
- ai_assert(progress);
-
- // Gather configuration properties for this run
- SetupProperties( pImp );
-
- // Construct a file system filter to improve our success ratio at reading external files
- FileSystemFilter filter(pFile,pIOHandler);
-
- // create a scene object to hold the data
- ScopeGuard<aiScene> sc(new aiScene());
-
- // dispatch importing
- try
- {
- InternReadFile( pFile, sc, &filter);
-
- } catch( const std::exception& err ) {
- // extract error description
- mErrorText = err.what();
- DefaultLogger::get()->error(mErrorText);
- return NULL;
- }
-
- // return what we gathered from the import.
- sc.dismiss();
- return sc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseImporter::SetupProperties(const Importer* /* pImp */)
-{
- // the default implementation does nothing
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
- const std::string& pFile,
- const char** tokens,
- unsigned int numTokens,
- unsigned int searchBytes /* = 200 */)
-{
- ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
- if (!pIOHandler)
- return false;
-
- boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
- if (pStream.get() ) {
- // read 200 characters from the file
- boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
- char* buffer = _buffer.get();
-
- const unsigned int read = pStream->Read(buffer,1,searchBytes);
- if (!read)
- return false;
-
- for (unsigned int i = 0; i < read;++i)
- buffer[i] = ::tolower(buffer[i]);
-
- // It is not a proper handling of unicode files here ...
- // ehm ... but it works in most cases.
- char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
- while (cur != end) {
- if (*cur)
- *cur2++ = *cur;
- ++cur;
- }
- *cur2 = '\0';
-
- for (unsigned int i = 0; i < numTokens;++i) {
- ai_assert(NULL != tokens[i]);
-
- if (::strstr(buffer,tokens[i])) {
- DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
- return true;
- }
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Simple check for file extension
-/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile,
- const char* ext0,
- const char* ext1,
- const char* ext2)
-{
- std::string::size_type pos = pFile.find_last_of('.');
-
- // no file extension - can't read
- if ( pos == std::string::npos)
- return false;
-
- const char* ext_real = & pFile[ pos+1 ];
- if ( !ASSIMP_stricmp(ext_real,ext0) )
- return true;
-
- // check for other, optional, file extensions
- if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
- return true;
-
- if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
- return true;
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get file extension from path
-/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
-{
- std::string::size_type pos = pFile.find_last_of('.');
-
- // no file extension at all
- if ( pos == std::string::npos)
- return "";
-
- std::string ret = pFile.substr(pos+1);
- std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check for magic bytes at the beginning of the file.
-/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
- const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
-{
- ai_assert(size <= 16 && _magic);
-
- if (!pIOHandler) {
- return false;
- }
- union {
- const char* magic;
- const uint16_t* magic_u16;
- const uint32_t* magic_u32;
- };
- magic = reinterpret_cast<const char*>(_magic);
- boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
- if (pStream.get() ) {
-
- // skip to offset
- pStream->Seek(offset,aiOrigin_SET);
-
- // read 'size' characters from the file
- union {
- char data[16];
- uint16_t data_u16[8];
- uint32_t data_u32[4];
- };
- if (size != pStream->Read(data,1,size)) {
- return false;
- }
-
- for (unsigned int i = 0; i < num; ++i) {
- // also check against big endian versions of tokens with size 2,4
- // that's just for convinience, the chance that we cause conflicts
- // is quite low and it can save some lines and prevent nasty bugs
- if (2 == size) {
- uint16_t rev = *magic_u16;
- ByteSwap::Swap(&rev);
- if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
- return true;
- }
- }
- else if (4 == size) {
- uint32_t rev = *magic_u32;
- ByteSwap::Swap(&rev);
- if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
- return true;
- }
- }
- else {
- // any length ... just compare
- if (!memcmp(magic,data,size)) {
- return true;
- }
- }
- magic += size;
- }
- }
- return false;
-}
-
-#include "../contrib/ConvertUTF/ConvertUTF.h"
-
-// ------------------------------------------------------------------------------------------------
-void ReportResult(ConversionResult res)
-{
- if (res == sourceExhausted) {
- DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
- }
- else if (res == sourceIllegal) {
- DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert to UTF8 data
-void BaseImporter::ConvertToUTF8(std::vector<char>& data)
-{
- ConversionResult result;
- if (data.size() < 8) {
- throw DeadlyImportError("File is too small");
- }
-
- // UTF 8 with BOM
- if ((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
- DefaultLogger::get()->debug("Found UTF-8 BOM ...");
-
- std::copy(data.begin()+3,data.end(),data.begin());
- data.resize(data.size()-3);
- return;
- }
-
- // UTF 32 BE with BOM
- if (*((uint32_t*)&data.front()) == 0xFFFE0000) {
-
- // swap the endianess ..
- for (uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
- AI_SWAP4P(p);
- }
- }
-
- // UTF 32 LE with BOM
- if (*((uint32_t*)&data.front()) == 0x0000FFFE) {
- DefaultLogger::get()->debug("Found UTF-32 BOM ...");
-
- const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
- char* dstart,*dend;
- std::vector<char> output;
- do {
- output.resize(output.size()?output.size()*3/2:data.size()/2);
- dstart = &output.front(),dend = &output.back()+1;
-
- result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
- } while (result == targetExhausted);
-
- ReportResult(result);
-
- // copy to output buffer.
- const size_t outlen = (size_t)(dstart-&output.front());
- data.assign(output.begin(),output.begin()+outlen);
- return;
- }
-
- // UTF 16 BE with BOM
- if (*((uint16_t*)&data.front()) == 0xFFFE) {
-
- // swap the endianess ..
- for (uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
- ByteSwap::Swap2(p);
- }
- }
-
- // UTF 16 LE with BOM
- if (*((uint16_t*)&data.front()) == 0xFEFF) {
- DefaultLogger::get()->debug("Found UTF-16 BOM ...");
-
- const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)&data.back()+1;
- char* dstart,*dend;
- std::vector<char> output;
- do {
- output.resize(output.size()?output.size()*3/2:data.size()*3/4);
- dstart = &output.front(),dend = &output.back()+1;
-
- result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
- } while (result == targetExhausted);
-
- ReportResult(result);
-
- // copy to output buffer.
- const size_t outlen = (size_t)(dstart-&output.front());
- data.assign(output.begin(),output.begin()+outlen);
- return;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseImporter::TextFileToBuffer(IOStream* stream,
- std::vector<char>& data)
-{
- ai_assert(NULL != stream);
-
- const size_t fileSize = stream->FileSize();
- if (!fileSize) {
- throw DeadlyImportError("File is empty");
- }
-
- data.reserve(fileSize+1);
- data.resize(fileSize);
- if (fileSize != stream->Read( &data[0], 1, fileSize)) {
- throw DeadlyImportError("File read error");
- }
-
- ConvertToUTF8(data);
-
- // append a binary zero to simplify string parsing
- data.push_back(0);
-}
-
-// ------------------------------------------------------------------------------------------------
-namespace Assimp
-{
- // Represents an import request
- struct LoadRequest
- {
- LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
- : file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
- {
- if (_map)
- map = *_map;
- }
-
- const std::string file;
- unsigned int flags;
- unsigned int refCnt;
- aiScene* scene;
- bool loaded;
- BatchLoader::PropertyMap map;
- unsigned int id;
-
- bool operator== (const std::string& f) {
- return file == f;
- }
- };
-}
-
-// ------------------------------------------------------------------------------------------------
-// BatchLoader::pimpl data structure
-struct Assimp::BatchData
-{
- BatchData()
- : next_id(0xffff)
- {}
-
- // IO system to be used for all imports
- IOSystem* pIOSystem;
-
- // Importer used to load all meshes
- Importer* pImporter;
-
- // List of all imports
- std::list<LoadRequest> requests;
-
- // Base path
- std::string pathBase;
-
- // Id for next item
- unsigned int next_id;
-};
-
-// ------------------------------------------------------------------------------------------------
-BatchLoader::BatchLoader(IOSystem* pIO)
-{
- ai_assert(NULL != pIO);
-
- data = new BatchData();
- data->pIOSystem = pIO;
-
- data->pImporter = new Importer();
- data->pImporter->SetIOHandler(data->pIOSystem);
-}
-
-// ------------------------------------------------------------------------------------------------
-BatchLoader::~BatchLoader()
-{
- // delete all scenes wthat have not been polled by the user
- for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
-
- delete (*it).scene;
- }
- data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
- delete data->pImporter;
- delete data;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-unsigned int BatchLoader::AddLoadRequest (const std::string& file,
- unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
-{
- ai_assert(!file.empty());
-
- // check whether we have this loading request already
- std::list<LoadRequest>::iterator it;
- for (it = data->requests.begin();it != data->requests.end(); ++it) {
-
- // Call IOSystem's path comparison function here
- if (data->pIOSystem->ComparePaths((*it).file,file)) {
-
- if (map) {
- if (!((*it).map == *map))
- continue;
- }
- else if (!(*it).map.empty())
- continue;
-
- (*it).refCnt++;
- return (*it).id;
- }
- }
-
- // no, we don't have it. So add it to the queue ...
- data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
- return data->next_id++;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiScene* BatchLoader::GetImport (unsigned int which)
-{
- for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
-
- if ((*it).id == which && (*it).loaded) {
-
- aiScene* sc = (*it).scene;
- if (!(--(*it).refCnt)) {
- data->requests.erase(it);
- }
- return sc;
- }
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BatchLoader::LoadAll()
-{
- // no threaded implementation for the moment
- for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
- // force validation in debug builds
- unsigned int pp = (*it).flags;
-#ifdef _DEBUG
- pp |= aiProcess_ValidateDataStructure;
-#endif
- // setup config properties if necessary
- data->pImporter->pimpl->mFloatProperties = (*it).map.floats;
- data->pImporter->pimpl->mIntProperties = (*it).map.ints;
- data->pImporter->pimpl->mStringProperties = (*it).map.strings;
-
- if (!DefaultLogger::isNullLogger())
- {
- DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
- DefaultLogger::get()->info("File: " + (*it).file);
- }
- data->pImporter->ReadFile((*it).file,pp);
- (*it).scene = const_cast<aiScene*>(data->pImporter->GetOrphanedScene());
- (*it).loaded = true;
-
- DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
- }
-}
-
-
-
-
diff --git a/3rdparty/assimp/code/BaseImporter.h b/3rdparty/assimp/code/BaseImporter.h
deleted file mode 100644
index 9da05713..00000000
--- a/3rdparty/assimp/code/BaseImporter.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Definition of the base class for all importer worker classes. */
-#ifndef INCLUDED_AI_BASEIMPORTER_H
-#define INCLUDED_AI_BASEIMPORTER_H
-
-#include "Exceptional.h"
-
-#include <string>
-#include <map>
-#include <vector>
-#include "./../include/aiTypes.h"
-
-struct aiScene;
-
-namespace Assimp {
-
-class IOSystem;
-class Importer;
-class BaseImporter;
-class BaseProcess;
-class SharedPostProcessInfo;
-class IOStream;
-
-// utility to do char4 to uint32 in a portable manner
-#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
- (string[1] << 16) + (string[2] << 8) + string[3]))
-
-// ---------------------------------------------------------------------------
-template <typename T>
-struct ScopeGuard
-{
- ScopeGuard(T* obj) : obj(obj), mdismiss() {}
- ~ScopeGuard () throw() {
- if (!mdismiss) {
- delete obj;
- }
- obj = NULL;
- }
-
- T* dismiss() {
- mdismiss=true;
- return obj;
- }
-
- operator T*() {
- return obj;
- }
-
- T* operator -> () {
- return obj;
- }
-
-private:
- T* obj;
- bool mdismiss;
-};
-
-//! @cond never
-// ---------------------------------------------------------------------------
-/** @brief Internal PIMPL implementation for Assimp::Importer
- *
- * Using this idiom here allows us to drop the dependency from
- * std::vector and std::map in the public headers. Furthermore we are dropping
- * any STL interface problems caused by mismatching STL settings. All
- * size calculation are now done by us, not the app heap. */
-class ASSIMP_API ImporterPimpl
-{
-public:
-
- // Data type to store the key hash
- typedef unsigned int KeyType;
-
- // typedefs for our three configuration maps.
- // We don't need more, so there is no need for a generic solution
- typedef std::map<KeyType, int> IntPropertyMap;
- typedef std::map<KeyType, float> FloatPropertyMap;
- typedef std::map<KeyType, std::string> StringPropertyMap;
-
-public:
-
- /** IO handler to use for all file accesses. */
- IOSystem* mIOHandler;
- bool mIsDefaultHandler;
-
- /** Progress handler for feedback. */
- ProgressHandler* mProgressHandler;
- bool mIsDefaultProgressHandler;
-
- /** Format-specific importer worker objects - one for each format we can read.*/
- std::vector<BaseImporter*> mImporter;
-
- /** Post processing steps we can apply at the imported data. */
- std::vector<BaseProcess*> mPostProcessingSteps;
-
- /** The imported data, if ReadFile() was successful, NULL otherwise. */
- aiScene* mScene;
-
- /** The error description, if there was one. */
- std::string mErrorString;
-
- /** List of integer properties */
- IntPropertyMap mIntProperties;
-
- /** List of floating-point properties */
- FloatPropertyMap mFloatProperties;
-
- /** List of string properties */
- StringPropertyMap mStringProperties;
-
- /** Used for testing - extra verbose mode causes the ValidateDataStructure-Step
- * to be executed before and after every single postprocess step */
- bool bExtraVerbose;
-
- /** Used by post-process steps to share data */
- SharedPostProcessInfo* mPPShared;
-};
-//! @endcond
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
- * for all importer worker classes.
- *
- * The interface defines two functions: CanRead() is used to check if the
- * importer can handle the format of the given file. If an implementation of
- * this function returns true, the importer then calls ReadFile() which
- * imports the given file. ReadFile is not overridable, it just calls
- * InternReadFile() and catches any ImportErrorException that might occur.
- */
-class ASSIMP_API BaseImporter
-{
- friend class Importer;
-
-protected:
-
- /** Constructor to be privately used by #Importer */
- BaseImporter();
-
- /** Destructor, private as well */
- virtual ~BaseImporter();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- *
- * The implementation should be as quick as possible. A check for
- * the file extension is enough. If no suitable loader is found with
- * this strategy, CanRead() is called again, the 'checkSig' parameter
- * set to true this time. Now the implementation is expected to
- * perform a full check of the file structure, possibly searching the
- * first bytes of the file for magic identifiers or keywords.
- *
- * @param pFile Path and file name of the file to be examined.
- * @param pIOHandler The IO handler to use for accessing any file.
- * @param checkSig Set to true if this method is called a second time.
- * This time, the implementation may take more time to examine the
- * contents of the file to be loaded for magic bytes, keywords, etc
- * to be able to load files with unknown/not existent file extensions.
- * @return true if the class can read this file, false if not.
- */
- virtual bool CanRead(
- const std::string& pFile,
- IOSystem* pIOHandler,
- bool checkSig
- ) const = 0;
-
- // -------------------------------------------------------------------
- /** Imports the given file and returns the imported data.
- * If the import succeeds, ownership of the data is transferred to
- * the caller. If the import fails, NULL is returned. The function
- * takes care that any partially constructed data is destroyed
- * beforehand.
- *
- * @param pImp #Importer object hosting this loader.
- * @param pFile Path of the file to be imported.
- * @param pIOHandler IO-Handler used to open this and possible other files.
- * @return The imported data or NULL if failed. If it failed a
- * human-readable error description can be retrieved by calling
- * GetErrorText()
- *
- * @note This function is not intended to be overridden. Implement
- * InternReadFile() to do the import. If an exception is thrown somewhere
- * in InternReadFile(), this function will catch it and transform it into
- * a suitable response to the caller.
- */
- aiScene* ReadFile(
- const Importer* pImp,
- const std::string& pFile,
- IOSystem* pIOHandler
- );
-
- // -------------------------------------------------------------------
- /** Returns the error description of the last error that occured.
- * @return A description of the last error that occured. An empty
- * string if there was no error.
- */
- const std::string& GetErrorText() const {
- return mErrorText;
- }
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- * @param pImp Importer instance
- */
- virtual void SetupProperties(
- const Importer* pImp
- );
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * Implementations are expected to insert() all file extensions
- * handled by them into the extension set. A loader capable of
- * reading certain files with the extension BLA would place the
- * string bla (lower-case!) in the output set.
- * @param extensions Output set. */
- virtual void GetExtensionList(
- std::set<std::string>& extensions
- ) = 0;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure. The
- * function is expected to throw an ImportErrorException if there is
- * an error. If it terminates normally, the data in aiScene is
- * expected to be correct. Override this function to implement the
- * actual importing.
- * <br>
- * The output scene must meet the following requirements:<br>
- * <ul>
- * <li>At least a root node must be there, even if its only purpose
- * is to reference one mesh.</li>
- * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
- * in the mesh are determined automatically in this case.</li>
- * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
- * In fact this means that every vertex that is referenced by
- * a face is unique. Or the other way round: a vertex index may
- * not occur twice in a single aiMesh.</li>
- * <li>aiAnimation::mDuration may be -1. Assimp determines the length
- * of the animation automatically in this case as the length of
- * the longest animation channel.</li>
- * <li>aiMesh::mBitangents may be NULL if tangents and normals are
- * given. In this case bitangents are computed as the cross product
- * between normal and tangent.</li>
- * <li>There needn't be a material. If none is there a default material
- * is generated. However, it is recommended practice for loaders
- * to generate a default material for yourself that matches the
- * default material setting for the file format better than Assimp's
- * generic default material. Note that default materials *should*
- * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
- * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
- * texture. </li>
- * </ul>
- * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
- * <li> at least one mesh must be there</li>
- * <li> there may be no meshes with 0 vertices or faces</li>
- * </ul>
- * This won't be checked (except by the validation step): Assimp will
- * crash if one of the conditions is not met!
- *
- * @param pFile Path of the file to be imported.
- * @param pScene The scene object to hold the imported data.
- * NULL is not a valid parameter.
- * @param pIOHandler The IO handler to use for any file access.
- * NULL is not a valid parameter. */
- virtual void InternReadFile(
- const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler
- ) = 0;
-
-public: // static utilities
-
- // -------------------------------------------------------------------
- /** A utility for CanRead().
- *
- * The function searches the header of a file for a specific token
- * and returns true if this token is found. This works for text
- * files only. There is a rudimentary handling of UNICODE files.
- * The comparison is case independent.
- *
- * @param pIOSystem IO System to work with
- * @param file File name of the file
- * @param tokens List of tokens to search for
- * @param numTokens Size of the token array
- * @param searchBytes Number of bytes to be searched for the tokens.
- */
- static bool SearchFileHeaderForToken(
- IOSystem* pIOSystem,
- const std::string& file,
- const char** tokens,
- unsigned int numTokens,
- unsigned int searchBytes = 200);
-
-
- // -------------------------------------------------------------------
- /** @brief Check whether a file has a specific file extension
- * @param pFile Input file
- * @param ext0 Extension to check for. Lowercase characters only, no dot!
- * @param ext1 Optional second extension
- * @param ext2 Optional third extension
- * @note Case-insensitive
- */
- static bool SimpleExtensionCheck (
- const std::string& pFile,
- const char* ext0,
- const char* ext1 = NULL,
- const char* ext2 = NULL);
-
- // -------------------------------------------------------------------
- /** @brief Extract file extension from a string
- * @param pFile Input file
- * @return Extension without trailing dot, all lowercase
- */
- static std::string GetExtension (
- const std::string& pFile);
-
- // -------------------------------------------------------------------
- /** @brief Check whether a file starts with one or more magic tokens
- * @param pFile Input file
- * @param pIOHandler IO system to be used
- * @param magic n magic tokens
- * @params num Size of magic
- * @param offset Offset from file start where tokens are located
- * @param Size of one token, in bytes. Maximally 16 bytes.
- * @return true if one of the given tokens was found
- *
- * @note For convinence, the check is also performed for the
- * byte-swapped variant of all tokens (big endian). Only for
- * tokens of size 2,4.
- */
- static bool CheckMagicToken(
- IOSystem* pIOHandler,
- const std::string& pFile,
- const void* magic,
- unsigned int num,
- unsigned int offset = 0,
- unsigned int size = 4);
-
- // -------------------------------------------------------------------
- /** An utility for all text file loaders. It converts a file to our
- * UTF8 character set. Errors are reported, but ignored.
- *
- * @param data File buffer to be converted to UTF8 data. The buffer
- * is resized as appropriate. */
- static void ConvertToUTF8(
- std::vector<char>& data);
-
- // -------------------------------------------------------------------
- /** Utility for text file loaders which copies the contents of the
- * file into a memory buffer and converts it to our UTF8
- * representation.
- * @param stream Stream to read from.
- * @param data Output buffer to be resized and filled with the
- * converted text file data. The buffer is terminated with
- * a binary 0. */
- static void TextFileToBuffer(
- IOStream* stream,
- std::vector<char>& data);
-
-protected:
-
- /** Error description in case there was one. */
- std::string mErrorText;
-
- /** Currently set progress handler */
- ProgressHandler* progress;
-};
-
-struct BatchData;
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: A helper class for the pleasure of importers
- * which need to load many extern meshes recursively.
- *
- * The class uses several threads to load these meshes (or at least it
- * could, this has not yet been implemented at the moment).
- *
- * @note The class may not be used by more than one thread*/
-class ASSIMP_API BatchLoader
-{
- // friend of Importer
-
-public:
-
- //! @cond never
- // -------------------------------------------------------------------
- /** Wraps a full list of configuration properties for an importer.
- * Properties can be set using SetGenericProperty */
- struct PropertyMap
- {
- ImporterPimpl::IntPropertyMap ints;
- ImporterPimpl::FloatPropertyMap floats;
- ImporterPimpl::StringPropertyMap strings;
-
- bool operator == (const PropertyMap& prop) const {
- // fixme: really isocpp? gcc complains
- return ints == prop.ints && floats == prop.floats && strings == prop.strings;
- }
-
- bool empty () const {
- return ints.empty() && floats.empty() && strings.empty();
- }
- };
- //! @endcond
-
-public:
-
-
- // -------------------------------------------------------------------
- /** Construct a batch loader from a given IO system to be used
- * to acess external files */
- BatchLoader(IOSystem* pIO);
- ~BatchLoader();
-
-
- // -------------------------------------------------------------------
- /** Add a new file to the list of files to be loaded.
- * @param file File to be loaded
- * @param steps Post-processing steps to be executed on the file
- * @param map Optional configuration properties
- * @return 'Load request channel' - an unique ID that can later
- * be used to access the imported file data.
- * @see GetImport */
- unsigned int AddLoadRequest (
- const std::string& file,
- unsigned int steps = 0,
- const PropertyMap* map = NULL
- );
-
-
- // -------------------------------------------------------------------
- /** Get an imported scene.
- * This polls the import from the internal request list.
- * If an import is requested several times, this function
- * can be called several times, too.
- *
- * @param which LRWC returned by AddLoadRequest().
- * @return NULL if there is no scene with this file name
- * in the queue of the scene hasn't been loaded yet. */
- aiScene* GetImport(
- unsigned int which
- );
-
-
- // -------------------------------------------------------------------
- /** Waits until all scenes have been loaded. This returns
- * immediately if no scenes are queued.*/
- void LoadAll();
-
-private:
-
- // No need to have that in the public API ...
- BatchData* data;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_BASEIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/BaseProcess.cpp b/3rdparty/assimp/code/BaseProcess.cpp
deleted file mode 100644
index c5970fba..00000000
--- a/3rdparty/assimp/code/BaseProcess.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of BaseProcess */
-
-#include "AssimpPCH.h"
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BaseProcess::BaseProcess()
-: shared()
-, progress()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BaseProcess::~BaseProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseProcess::ExecuteOnScene( Importer* pImp)
-{
- ai_assert(NULL != pImp && NULL != pImp->pimpl->mScene);
-
- progress = pImp->GetProgressHandler();
- ai_assert(progress);
-
- SetupProperties( pImp );
-
- // catch exceptions thrown inside the PostProcess-Step
- try
- {
- Execute(pImp->pimpl->mScene);
-
- } catch( const std::exception& err ) {
-
- // extract error description
- pImp->pimpl->mErrorString = err.what();
- DefaultLogger::get()->error(pImp->pimpl->mErrorString);
-
- // and kill the partially imported data
- delete pImp->pimpl->mScene;
- pImp->pimpl->mScene = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseProcess::SetupProperties(const Importer* /* pImp */)
-{
- // the default implementation does nothing
-}
diff --git a/3rdparty/assimp/code/BaseProcess.h b/3rdparty/assimp/code/BaseProcess.h
deleted file mode 100644
index cd8bda0c..00000000
--- a/3rdparty/assimp/code/BaseProcess.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Base class of all import post processing steps */
-#ifndef INCLUDED_AI_BASEPROCESS_H
-#define INCLUDED_AI_BASEPROCESS_H
-
-#include <map>
-
-#include "../include/aiTypes.h"
-#include "GenericProperty.h"
-
-struct aiScene;
-
-namespace Assimp {
-
-class Importer;
-
-// ---------------------------------------------------------------------------
-/** Helper class to allow post-processing steps to interact with each other.
- *
- * The class maintains a simple property list that can be used by pp-steps
- * to provide additional information to other steps. This is primarily
- * intended for cross-step optimizations.
- */
-class ASSIMP_API SharedPostProcessInfo
-{
-public:
-
- struct Base
- {
- virtual ~Base()
- {}
- };
-
- //! Represents data that is allocated on the heap, thus needs to be deleted
- template <typename T>
- struct THeapData : public Base
- {
- THeapData(T* in)
- : data (in)
- {}
-
- ~THeapData()
- {
- delete data;
- }
- T* data;
- };
-
- //! Represents static, by-value data not allocated on the heap
- template <typename T>
- struct TStaticData : public Base
- {
- TStaticData(T in)
- : data (in)
- {}
-
- ~TStaticData()
- {}
-
- T data;
- };
-
- // some typedefs for cleaner code
- typedef unsigned int KeyType;
- typedef std::map<KeyType, Base*> PropertyMap;
-
-public:
-
- //! Destructor
- ~SharedPostProcessInfo()
- {
- Clean();
- }
-
- //! Remove all stored properties from the table
- void Clean()
- {
- // invoke the virtual destructor for all stored properties
- for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
- it != end; ++it)
- {
- delete (*it).second;
- }
- pmap.clear();
- }
-
- //! Add a heap property to the list
- template <typename T>
- void AddProperty( const char* name, T* in ){
- AddProperty(name,(Base*)new THeapData<T>(in));
- }
-
- //! Add a static by-value property to the list
- template <typename T>
- void AddProperty( const char* name, T in ){
- AddProperty(name,(Base*)new TStaticData<T>(in));
- }
-
-
- //! Get a heap property
- template <typename T>
- bool GetProperty( const char* name, T*& out ) const
- {
- THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
- if (!t)
- {
- out = NULL;
- return false;
- }
- out = t->data;
- return true;
- }
-
- //! Get a static, by-value property
- template <typename T>
- bool GetProperty( const char* name, T& out ) const
- {
- TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
- if (!t)return false;
- out = t->data;
- return true;
- }
-
- //! Remove a property of a specific type
- void RemoveProperty( const char* name) {
- SetGenericPropertyPtr<Base>(pmap,name,NULL);
- }
-
-private:
-
- void AddProperty( const char* name, Base* data) {
- SetGenericPropertyPtr<Base>(pmap,name,data);
- }
-
- Base* GetPropertyInternal( const char* name) const {
- return GetGenericProperty<Base*>(pmap,name,NULL);
- }
-
-private:
-
- //! Map of all stored properties
- PropertyMap pmap;
-};
-
-#if 0
-
-// ---------------------------------------------------------------------------
-/** @brief Represents a dependency table for a postprocessing steps.
- *
- * For future use.
- */
- struct PPDependencyTable
- {
- unsigned int execute_me_before_these;
- unsigned int execute_me_after_these;
- unsigned int only_if_these_are_not_specified;
- unsigned int mutually_exclusive_with;
- };
-
-#endif
-
-
-#define AI_SPP_SPATIAL_SORT "$Spat"
-
-// ---------------------------------------------------------------------------
-/** The BaseProcess defines a common interface for all post processing steps.
- * A post processing step is run after a successful import if the caller
- * specified the corresponding flag when calling ReadFile().
- * Enum #aiPostProcessSteps defines which flags are available.
- * After a successful import the Importer iterates over its internal array
- * of processes and calls IsActive() on each process to evaluate if the step
- * should be executed. If the function returns true, the class' Execute()
- * function is called subsequently.
- */
-class ASSIMP_API BaseProcess
-{
- friend class Importer;
-
-public:
-
- /** Constructor to be privately used by Importer */
- BaseProcess();
-
- /** Destructor, private as well */
- virtual ~BaseProcess();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with. A
- * bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- virtual bool IsActive( unsigned int pFlags) const = 0;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * The function deletes the scene if the postprocess step fails (
- * the object pointer will be set to NULL).
- * @param pImp Importer instance (pImp->mScene must be valid)
- */
- void ExecuteOnScene( Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * A process should throw an ImportErrorException* if it fails.
- * This method must be implemented by deriving classes.
- * @param pScene The imported data to work at.
- */
- virtual void Execute( aiScene* pScene) = 0;
-
-
- // -------------------------------------------------------------------
- /** Assign a new SharedPostProcessInfo to the step. This object
- * allows multiple postprocess steps to share data.
- * @param sh May be NULL
- */
- inline void SetSharedData(SharedPostProcessInfo* sh) {
- shared = sh;
- }
-
- // -------------------------------------------------------------------
- /** Get the shared data that is assigned to the step.
- */
- inline SharedPostProcessInfo* GetSharedData() {
- return shared;
- }
-
-protected:
-
- /** See the doc of #SharedPostProcessInfo for more details */
- SharedPostProcessInfo* shared;
-
- /** Currently active progress handler */
- ProgressHandler* progress;
-};
-
-
-} // end of namespace Assimp
-
-#endif // AI_BASEPROCESS_H_INC
diff --git a/3rdparty/assimp/code/BlenderDNA.cpp b/3rdparty/assimp/code/BlenderDNA.cpp
deleted file mode 100644
index 5206ab13..00000000
--- a/3rdparty/assimp/code/BlenderDNA.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderDNA.cpp
- * @brief Implementation of the Blender `DNA`, that is its own
- * serialized set of data structures.
- */
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-#include "BlenderDNA.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-using namespace Assimp::Formatter;
-
-#define for_each BOOST_FOREACH
-bool match4(StreamReaderAny& stream, const char* string) {
- char tmp[] = {
- (stream).GetI1(),
- (stream).GetI1(),
- (stream).GetI1(),
- (stream).GetI1()
- };
- return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
-}
-
-struct Type {
- size_t size;
- std::string name;
-};
-
-// ------------------------------------------------------------------------------------------------
-void DNAParser :: Parse ()
-{
- StreamReaderAny& stream = *db.reader.get();
- DNA& dna = db.dna;
-
- if (!match4(stream,"SDNA")) {
- throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
- }
-
- // name dictionary
- if (!match4(stream,"NAME")) {
- throw DeadlyImportError("BlenderDNA: Expected NAME field");
- }
-
- std::vector<std::string> names (stream.GetI4());
- for_each(std::string& s, names) {
- while (char c = stream.GetI1()) {
- s += c;
- }
- }
-
- // type dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1()) {};
- if (!match4(stream,"TYPE")) {
- throw DeadlyImportError("BlenderDNA: Expected TYPE field");
- }
-
- std::vector<Type> types (stream.GetI4());
- for_each(Type& s, types) {
- while (char c = stream.GetI1()) {
- s.name += c;
- }
- }
-
- // type length dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1()) {};
- if (!match4(stream,"TLEN")) {
- throw DeadlyImportError("BlenderDNA: Expected TLEN field");
- }
-
- for_each(Type& s, types) {
- s.size = stream.GetI2();
- }
-
- // structures dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1()) {};
- if (!match4(stream,"STRC")) {
- throw DeadlyImportError("BlenderDNA: Expected STRC field");
- }
-
- size_t end = stream.GetI4(), fields = 0;
-
- dna.structures.reserve(end);
- for (size_t i = 0; i != end; ++i) {
-
- uint16_t n = stream.GetI2();
- if (n >= types.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid type index in structure name" ,n,
- " (there are only ", types.size(), " entries)"
- ));
- }
-
- // maintain separate indexes
- dna.indices[types[n].name] = dna.structures.size();
-
- dna.structures.push_back(Structure());
- Structure& s = dna.structures.back();
- s.name = types[n].name;
- //s.index = dna.structures.size()-1;
-
- n = stream.GetI2();
- s.fields.reserve(n);
-
- size_t offset = 0;
- for (size_t m = 0; m < n; ++m, ++fields) {
-
- uint16_t j = stream.GetI2();
- if (j >= types.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid type index in structure field ", j,
- " (there are only ", types.size(), " entries)"
- ));
- }
- s.fields.push_back(Field());
- Field& f = s.fields.back();
- f.offset = offset;
-
- f.type = types[j].name;
- f.size = types[j].size;
-
- j = stream.GetI2();
- if (j >= names.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid name index in structure field ", j,
- " (there are only ", names.size(), " entries)"
- ));
- }
-
- f.name = names[j];
- f.flags = 0u;
-
- // pointers always specify the size of the pointee instead of their own.
- // The pointer asterisk remains a property of the lookup name.
- if (f.name[0] == '*') {
- f.size = db.i64bit ? 8 : 4;
- f.flags |= FieldFlag_Pointer;
- }
-
- // arrays, however, specify the size of a single element so we
- // need to parse the (possibly multi-dimensional) array declaration
- // in order to obtain the actual size of the array in the file.
- // Also we need to alter the lookup name to include no array
- // brackets anymore or size fixup won't work (if our size does
- // not match the size read from the DNA).
- if (*f.name.rbegin() == ']') {
- const std::string::size_type rb = f.name.find('[');
- if (rb == std::string::npos) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Encountered invalid array declaration ",
- f.name
- ));
- }
-
- f.flags |= FieldFlag_Array;
- DNA::ExtractArraySize(f.name,f.array_sizes);
- f.name = f.name.substr(0,rb);
-
- f.size *= f.array_sizes[0] * f.array_sizes[1];
- }
-
- // maintain separate indexes
- s.indices[f.name] = s.fields.size()-1;
- offset += f.size;
- }
- s.size = offset;
- }
-
- DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
- " structures with totally ",fields," fields"));
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- dna.DumpToFile();
-#endif
-
- dna.AddPrimitiveStructures();
- dna.RegisterConverters();
-}
-
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
-
-#include <fstream>
-// ------------------------------------------------------------------------------------------------
-void DNA :: DumpToFile()
-{
- // we dont't bother using the VFS here for this is only for debugging.
- // (and all your bases are belong to us).
-
- std::ofstream f("dna.txt");
- if (f.fail()) {
- DefaultLogger::get()->error("Could not dump dna to dna.txt");
- return;
- }
- f << "Field format: type name offset size" << "\n";
- f << "Structure format: name size" << "\n";
-
- for_each(const Structure& s, structures) {
- f << s.name << " " << s.size << "\n\n";
- for_each(const Field& ff, s.fields) {
- f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
- }
- f << std::endl;
- }
- DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void DNA :: ExtractArraySize(
- const std::string& out,
- size_t array_sizes[2]
-)
-{
- array_sizes[0] = array_sizes[1] = 1;
- std::string::size_type pos = out.find('[');
- if (pos++ == std::string::npos) {
- return;
- }
- array_sizes[0] = strtol10(&out[pos]);
-
- pos = out.find('[',pos);
- if (pos++ == std::string::npos) {
- return;
- }
- array_sizes[1] = strtol10(&out[pos]);
-}
-
-// ------------------------------------------------------------------------------------------------
-boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
- const Structure& structure,
- const FileDatabase& db
-) const
-{
- std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
- if (it == converters.end()) {
- return boost::shared_ptr< ElemBase >();
- }
-
- boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
- (structure.*((*it).second.second))(ret,db);
-
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-DNA::FactoryPair DNA :: GetBlobToStructureConverter(
- const Structure& structure,
- const FileDatabase& /* db */
-) const
-{
- std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
- return it == converters.end() ? FactoryPair() : (*it).second;
-}
-
-// basing on http://www.blender.org/development/architecture/notes-on-sdna/
-// ------------------------------------------------------------------------------------------------
-void DNA :: AddPrimitiveStructures()
-{
- // NOTE: these are just dummies. Their presence enforces
- // Structure::Convert<target_type> to be called on these
- // empty structures. These converters are special
- // overloads which scan the name of the structure and
- // perform the required data type conversion if one
- // of these special names is found in the structure
- // in question.
-
- indices["int"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "int";
- structures.back().size = 4;
-
- indices["short"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "short";
- structures.back().size = 2;
-
-
- indices["char"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "char";
- structures.back().size = 1;
-
-
- indices["float"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "float";
- structures.back().size = 4;
-
-
- indices["double"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "double";
- structures.back().size = 8;
-
- // no long, seemingly.
-}
-
-// ------------------------------------------------------------------------------------------------
-void SectionParser :: Next()
-{
- stream.SetCurrentPos(current.start + current.size);
-
- const char tmp[] = {
- stream.GetI1(),
- stream.GetI1(),
- stream.GetI1(),
- stream.GetI1()
- };
- current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
-
- current.size = stream.GetI4();
- current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
-
- current.dna_index = stream.GetI4();
- current.num = stream.GetI4();
-
- current.start = stream.GetCurrentPos();
- if (stream.GetRemainingSizeToLimit() < current.size) {
- throw DeadlyImportError("BLEND: invalid size of file block");
- }
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- DefaultLogger::get()->debug(current.id);
-#endif
-}
-
-
-
-#endif
diff --git a/3rdparty/assimp/code/BlenderDNA.h b/3rdparty/assimp/code/BlenderDNA.h
deleted file mode 100644
index 8bf237da..00000000
--- a/3rdparty/assimp/code/BlenderDNA.h
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderDNA.h
- * @brief Blender `DNA` (file format specification embedded in
- * blend file itself) loader.
- */
-#ifndef INCLUDED_AI_BLEND_DNA_H
-#define INCLUDED_AI_BLEND_DNA_H
-
-#include "BaseImporter.h"
-#include "TinyFormatter.h"
-
-// enable verbose log output. really verbose, so be careful.
-#ifdef _DEBUG
-# define ASSIMP_BUILD_BLENDER_DEBUG
-#endif
-
-// #define ASSIMP_BUILD_BLENDER_NO_STATS
-
-namespace Assimp {
- template <bool,bool> class StreamReader;
- typedef StreamReader<true,true> StreamReaderAny;
-
- namespace Blender {
- class FileDatabase;
- struct FileBlockHead;
-
- template <template <typename> class TOUT>
- class ObjectCache;
-
-// -------------------------------------------------------------------------------
-/** Exception class used by the blender loader to selectively catch exceptions
- * thrown in its own code (DeadlyImportErrors thrown in general utility
- * functions are untouched then). If such an exception is not caught by
- * the loader itself, it will still be caught by Assimp due to its
- * ancestry. */
-// -------------------------------------------------------------------------------
-struct Error : DeadlyImportError
-{
- Error (const std::string& s)
- : DeadlyImportError(s)
- {}
-};
-
-// -------------------------------------------------------------------------------
-/** The only purpose of this structure is to feed a virtual dtor into its
- * descendents. It serves as base class for all data structure fields. */
-// -------------------------------------------------------------------------------
-struct ElemBase
-{
- virtual ~ElemBase() {}
-
- /** Type name of the element. The type
- * string points is the `c_str` of the `name` attribute of the
- * corresponding `Structure`, that is, it is only valid as long
- * as the DNA is not modified. The dna_type is only set if the
- * data type is not static, i.e. a boost::shared_ptr<ElemBase>
- * in the scene description would have its type resolved
- * at runtime, so this member is always set. */
- const char* dna_type;
-};
-
-
-// -------------------------------------------------------------------------------
-/** Represents a generic pointer to a memory location, which can be either 32
- * or 64 bits. These pointers are loaded from the BLEND file and finally
- * fixed to point to the real, converted representation of the objects
- * they used to point to.*/
-// -------------------------------------------------------------------------------
-struct Pointer
-{
- Pointer() : val() {}
- uint64_t val;
-};
-
-// -------------------------------------------------------------------------------
-/** Represents a generic offset within a BLEND file */
-// -------------------------------------------------------------------------------
-struct FileOffset
-{
- FileOffset() : val() {}
- uint64_t val;
-};
-
-// -------------------------------------------------------------------------------
-/** Dummy derivate of std::vector to be able to use it in templates simultaenously
- * with boost::shared_ptr, which takes only one template argument
- * while std::vector takes three. Also we need to provide some special member
- * functions of shared_ptr */
-// -------------------------------------------------------------------------------
-template <typename T>
-class vector : public std::vector<T>
-{
-public:
- using std::vector<T>::resize;
- using std::vector<T>::empty;
-
- void reset() {
- resize(0);
- }
-
- operator bool () const {
- return !empty();
- }
-};
-
-// -------------------------------------------------------------------------------
-/** Mixed flags for use in #Field */
-// -------------------------------------------------------------------------------
-enum FieldFlags
-{
- FieldFlag_Pointer = 0x1,
- FieldFlag_Array = 0x2
-};
-
-// -------------------------------------------------------------------------------
-/** Represents a single member of a data structure in a BLEND file */
-// -------------------------------------------------------------------------------
-struct Field
-{
- std::string name;
- std::string type;
-
- size_t size;
- size_t offset;
-
- /** Size of each array dimension. For flat arrays,
- * the second dimension is set to 1. */
- size_t array_sizes[2];
-
- /** Any of the #FieldFlags enumerated values */
- unsigned int flags;
-};
-
-// -------------------------------------------------------------------------------
-/** Range of possible behaviours for fields absend in the input file. Some are
- * mission critical so we need them, while others can silently be default
- * initialized and no animations are harmed. */
-// -------------------------------------------------------------------------------
-enum ErrorPolicy
-{
- /** Substitute default value and ignore */
- ErrorPolicy_Igno,
- /** Substitute default value and write to log */
- ErrorPolicy_Warn,
- /** Substitute a massive error message and crash the whole matrix. Its time for another zion */
- ErrorPolicy_Fail
-};
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
-# define ErrorPolicy_Igno ErrorPolicy_Warn
-#endif
-
-// -------------------------------------------------------------------------------
-/** Represents a data structure in a BLEND file. A Structure defines n fields
- * and their locatios and encodings the input stream. Usually, every
- * Structure instance pertains to one equally-named data structure in the
- * BlenderScene.h header. This class defines various utilities to map a
- * binary `blob` read from the file to such a structure instance with
- * meaningful contents. */
-// -------------------------------------------------------------------------------
-class Structure
-{
- template <template <typename> class> friend class ObjectCache;
-
-public:
-
- Structure()
- : cache_idx(-1)
- {}
-
-public:
-
- // publicly accessible members
- std::string name;
- vector< Field > fields;
- std::map<std::string, size_t> indices;
-
- size_t size;
-
-public:
-
- // --------------------------------------------------------
- /** Access a field of the structure by its canonical name. The pointer version
- * returns NULL on failure while the reference version raises an import error. */
- inline const Field& operator [] (const std::string& ss) const;
- inline const Field* Get (const std::string& ss) const;
-
- // --------------------------------------------------------
- /** Access a field of the structure by its index */
- inline const Field& operator [] (const size_t i) const;
-
- // --------------------------------------------------------
- inline bool operator== (const Structure& other) const {
- return name == other.name; // name is meant to be an unique identifier
- }
-
- // --------------------------------------------------------
- inline bool operator!= (const Structure& other) const {
- return name != other.name;
- }
-
-public:
-
- // --------------------------------------------------------
- /** Try to read an instance of the structure from the stream
- * and attempt to convert to `T`. This is done by
- * an appropriate specialization. If none is available,
- * a compiler complain is the result.
- * @param dest Destination value to be written
- * @param db File database, including input stream. */
- template <typename T> inline void Convert (T& dest,
- const FileDatabase& db) const;
-
-
-
- // --------------------------------------------------------
- // generic converter
- template <typename T>
- void Convert(boost::shared_ptr<ElemBase> in,const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // generic allocator
- template <typename T> boost::shared_ptr<ElemBase> Allocate() const;
-
-
-
- // --------------------------------------------------------
- // field parsing for 1d arrays
- template <int error_policy, typename T, size_t M>
- void ReadFieldArray(T (& out)[M], const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for 2d arrays
- template <int error_policy, typename T, size_t M, size_t N>
- void ReadFieldArray2(T (& out)[M][N], const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for pointer or dynamic array types
- // (boost::shared_ptr or boost::shared_array)
- template <int error_policy, template <typename> class TOUT, typename T>
- void ReadFieldPtr(TOUT<T>& out, const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for static arrays of pointer or dynamic
- // array types (boost::shared_ptr[] or boost::shared_array[])
- template <int error_policy, template <typename> class TOUT, typename T, size_t N>
- void ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for `normal` values
- template <int error_policy, typename T>
- void ReadField(T& out, const char* name,
- const FileDatabase& db) const;
-
-private:
-
- // --------------------------------------------------------
- template <template <typename> class TOUT, typename T>
- void ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
- const FileDatabase& db, const Field& f) const;
-
- // --------------------------------------------------------
- template <template <typename> class TOUT, typename T>
- void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
- const FileDatabase& db, const Field& f) const;
-
- // --------------------------------------------------------
- void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
- const FileDatabase& db, const Field& f) const;
-
- // --------------------------------------------------------
- inline const FileBlockHead* LocateFileBlockForAddress(
- const Pointer & ptrval,
- const FileDatabase& db) const;
-
-private:
-
- // ------------------------------------------------------------------------------
- template <typename T> T* _allocate(boost::shared_ptr<T>& out, size_t& s) const {
- out = boost::shared_ptr<T>(new T());
- s = 1;
- return out.get();
- }
-
- template <typename T> T* _allocate(vector<T>& out, size_t& s) const {
- out.resize(s);
- return s ? &out.front() : NULL;
- }
-
- // --------------------------------------------------------
- template <int error_policy>
- struct _defaultInitializer {
-
- template <typename T, unsigned int N>
- void operator ()(T (& out)[N], const char* = NULL) {
- for (unsigned int i = 0; i < N; ++i) {
- out[i] = T();
- }
- }
-
- template <typename T, unsigned int N, unsigned int M>
- void operator ()(T (& out)[N][M], const char* = NULL) {
- for (unsigned int i = 0; i < N; ++i) {
- for (unsigned int j = 0; j < M; ++j) {
- out[i][j] = T();
- }
- }
- }
-
- template <typename T>
- void operator ()(T& out, const char* = NULL) {
- out = T();
- }
- };
-
-private:
-
- mutable size_t cache_idx;
-};
-
-// --------------------------------------------------------
-template <> struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
-
- template <typename T>
- void operator ()(T& out, const char* reason = "<add reason>") {
- DefaultLogger::get()->warn(reason);
-
- // ... and let the show go on
- _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out);
- }
-};
-
-template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
-
- template <typename T>
- void operator ()(T& /*out*/,const char* = "") {
- // obviously, it is crucial that _DefaultInitializer is used
- // only from within a catch clause.
- throw;
- }
-};
-
-// -------------------------------------------------------------------------------------------------------
-template <> inline void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
- const Pointer & ptrval,
- const FileDatabase& db,
- const Field& f
- ) const;
-
-
-// -------------------------------------------------------------------------------
-/** Represents the full data structure information for a single BLEND file.
- * This data is extracted from the DNA1 chunk in the file.
- * #DNAParser does the reading and represents currently the only place where
- * DNA is altered.*/
-// -------------------------------------------------------------------------------
-class DNA
-{
-public:
-
- typedef void (Structure::*ConvertProcPtr) (
- boost::shared_ptr<ElemBase> in,
- const FileDatabase&
- ) const;
-
- typedef boost::shared_ptr<ElemBase> (
- Structure::*AllocProcPtr) () const;
-
- typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
-
-public:
-
- std::map<std::string, FactoryPair > converters;
- vector<Structure > structures;
- std::map<std::string, size_t> indices;
-
-public:
-
- // --------------------------------------------------------
- /** Access a structure by its canonical name, the pointer version returns NULL on failure
- * while the reference version raises an error. */
- inline const Structure& operator [] (const std::string& ss) const;
- inline const Structure* Get (const std::string& ss) const;
-
- // --------------------------------------------------------
- /** Access a structure by its index */
- inline const Structure& operator [] (const size_t i) const;
-
-public:
-
- // --------------------------------------------------------
- /** Add structure definitions for all the primitive types,
- * i.e. integer, short, char, float */
- void AddPrimitiveStructures();
-
- // --------------------------------------------------------
- /** Fill the @c converters member with converters for all
- * known data types. The implementation of this method is
- * in BlenderScene.cpp and is machine-generated.
- * Converters are used to quickly handle objects whose
- * exact data type is a runtime-property and not yet
- * known at compile time (consier Object::data).*/
- void RegisterConverters();
-
-
- // --------------------------------------------------------
- /** Take an input blob from the stream, interpret it according to
- * a its structure name and convert it to the intermediate
- * representation.
- * @param structure Destination structure definition
- * @param db File database.
- * @return A null pointer if no appropriate converter is available.*/
- boost::shared_ptr< ElemBase > ConvertBlobToStructure(
- const Structure& structure,
- const FileDatabase& db
- ) const;
-
- // --------------------------------------------------------
- /** Find a suitable conversion function for a given Structure.
- * Such a converter function takes a blob from the input
- * stream, reads as much as it needs, and builds up a
- * complete object in intermediate representation.
- * @param structure Destination structure definition
- * @param db File database.
- * @return A null pointer in .first if no appropriate converter is available.*/
- FactoryPair GetBlobToStructureConverter(
- const Structure& structure,
- const FileDatabase& db
- ) const;
-
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- // --------------------------------------------------------
- /** Dump the DNA to a text file. This is for debugging purposes.
- * The output file is `dna.txt` in the current working folder*/
- void DumpToFile();
-#endif
-
- // --------------------------------------------------------
- /** Extract array dimensions from a C array declaration, such
- * as `...[4][6]`. Returned string would be `...[][]`.
- * @param out
- * @param array_sizes Receive maximally two array dimensions,
- * the second element is set to 1 if the array is flat.
- * Both are set to 1 if the input is not an array.
- * @throw DeadlyImportError if more than 2 dimensions are
- * encountered. */
- static void ExtractArraySize(
- const std::string& out,
- size_t array_sizes[2]
- );
-};
-
-// special converters for primitive types
-template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const;
-
-// -------------------------------------------------------------------------------
-/** Describes a master file block header. Each master file sections holds n
- * elements of a certain SDNA structure (or otherwise unspecified data). */
-// -------------------------------------------------------------------------------
-struct FileBlockHead
-{
- // points right after the header of the file block
- StreamReaderAny::pos start;
-
- std::string id;
- size_t size;
-
- // original memory address of the data
- Pointer address;
-
- // index into DNA
- unsigned int dna_index;
-
- // number of structure instances to follow
- size_t num;
-
-
-
- // file blocks are sorted by address to quickly locate specific memory addresses
- bool operator < (const FileBlockHead& o) const {
- return address.val < o.address.val;
- }
-
- // for std::upper_bound
- operator const Pointer& () const {
- return address;
- }
-};
-
-// for std::upper_bound
-inline bool operator< (const Pointer& a, const Pointer& b) {
- return a.val < b.val;
-}
-
-// -------------------------------------------------------------------------------
-/** Utility to read all master file blocks in turn. */
-// -------------------------------------------------------------------------------
-class SectionParser
-{
-public:
-
- // --------------------------------------------------------
- /** @param stream Inout stream, must point to the
- * first section in the file. Call Next() once
- * to have it read.
- * @param ptr64 Pointer size in file is 64 bits? */
- SectionParser(StreamReaderAny& stream,bool ptr64)
- : stream(stream)
- , ptr64(ptr64)
- {
- current.size = current.start = 0;
- }
-
-public:
-
- // --------------------------------------------------------
- const FileBlockHead& GetCurrent() const {
- return current;
- }
-
-
-public:
-
- // --------------------------------------------------------
- /** Advance to the next section.
- * @throw DeadlyImportError if the last chunk was passed. */
- void Next();
-
-public:
-
- FileBlockHead current;
- StreamReaderAny& stream;
- bool ptr64;
-};
-
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
-// -------------------------------------------------------------------------------
-/** Import statistics, i.e. number of file blocks read*/
-// -------------------------------------------------------------------------------
-class Statistics {
-
-public:
-
- Statistics ()
- : fields_read ()
- , pointers_resolved ()
- , cache_hits ()
-// , blocks_read ()
- , cached_objects ()
- {}
-
-public:
-
- /** total number of fields we read */
- unsigned int fields_read;
-
- /** total number of resolved pointers */
- unsigned int pointers_resolved;
-
- /** number of pointers resolved from the cache */
- unsigned int cache_hits;
-
- /** number of blocks (from FileDatabase::entries)
- we did actually read from. */
- // unsigned int blocks_read;
-
- /** objects in FileData::cache */
- unsigned int cached_objects;
-};
-#endif
-
-// -------------------------------------------------------------------------------
-/** The object cache - all objects addressed by pointers are added here. This
- * avoids circular references and avoids object duplication. */
-// -------------------------------------------------------------------------------
-template <template <typename> class TOUT>
-class ObjectCache
-{
-public:
-
- typedef std::map< Pointer, TOUT<ElemBase> > StructureCache;
-
-public:
-
- ObjectCache(const FileDatabase& db)
- : db(db)
- {
- // currently there are only ~400 structure records per blend file.
- // we read only a small part of them and don't cache objects
- // which we don't need, so this should suffice.
- caches.reserve(64);
- }
-
-public:
-
- // --------------------------------------------------------
- /** Check whether a specific item is in the cache.
- * @param s Data type of the item
- * @param out Output pointer. Unchanged if the
- * cache doens't know the item yet.
- * @param ptr Item address to look for. */
- template <typename T> void get (
- const Structure& s,
- TOUT<T>& out,
- const Pointer& ptr) const;
-
- // --------------------------------------------------------
- /** Add an item to the cache after the item has
- * been fully read. Do not insert anything that
- * may be faulty or might cause the loading
- * to abort.
- * @param s Data type of the item
- * @param out Item to insert into the cache
- * @param ptr address (cache key) of the item. */
- template <typename T> void set
- (const Structure& s,
- const TOUT<T>& out,
- const Pointer& ptr);
-
-private:
-
- mutable vector<StructureCache> caches;
- const FileDatabase& db;
-};
-
-// -------------------------------------------------------------------------------
-// -------------------------------------------------------------------------------
-template <> class ObjectCache<Blender::vector>
-{
-public:
-
- ObjectCache(const FileDatabase&) {}
-
- template <typename T> void get(const Structure&, vector<T>& /*t*/, const Pointer&) {}
- template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {}
-};
-
-#ifdef _MSC_VER
-# pragma warning(disable:4355)
-#endif
-
-// -------------------------------------------------------------------------------
-/** Memory representation of a full BLEND file and all its dependencies. The
- * output aiScene is constructed from an instance of this data structure. */
-// -------------------------------------------------------------------------------
-class FileDatabase
-{
- template <template <typename> class TOUT> friend class ObjectCache;
-
-public:
-
-
- FileDatabase()
- : _cacheArrays(*this)
- , _cache(*this)
- , next_cache_idx()
- {}
-
-public:
-
- // publicly accessible fields
- bool i64bit;
- bool little;
-
- DNA dna;
- boost::shared_ptr< StreamReaderAny > reader;
- vector< FileBlockHead > entries;
-
-public:
-
- Statistics& stats() const {
- return _stats;
- }
-
- // For all our templates to work on both shared_ptr's and vector's
- // using the same code, a dummy cache for arrays is provided. Actually,
- // arrays of objects are never cached because we can't easily
- // ensure their proper destruction.
- template <typename T>
- ObjectCache<boost::shared_ptr>& cache(boost::shared_ptr<T>& /* in */) const {
- return _cache;
- }
-
- template <typename T>
- ObjectCache<vector>& cache(vector<T>& /*in*/) const {
- return _cacheArrays;
- }
-
-private:
-
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- mutable Statistics _stats;
-#endif
-
- mutable ObjectCache<vector> _cacheArrays;
- mutable ObjectCache<boost::shared_ptr> _cache;
-
- mutable size_t next_cache_idx;
-};
-
-#ifdef _MSC_VER
-# pragma warning(default:4355)
-#endif
-
-// -------------------------------------------------------------------------------
-/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
-// -------------------------------------------------------------------------------
-class DNAParser
-{
-
-public:
-
- /** Bind the parser to a empty DNA and an input stream */
- DNAParser(FileDatabase& db)
- : db(db)
- {}
-
-public:
-
- // --------------------------------------------------------
- /** Locate the DNA in the file and parse it. The input
- * stream is expected to point to the beginning of the DN1
- * chunk at the time this method is called and is
- * undefined afterwards.
- * @throw DeadlyImportError if the DNA cannot be read.
- * @note The position of the stream pointer is undefined
- * afterwards.*/
- void Parse ();
-
-public:
-
- /** Obtain a reference to the extracted DNA information */
- const Blender::DNA& GetDNA() const {
- return db.dna;
- }
-
-private:
-
- FileDatabase& db;
-};
-
- } // end Blend
-} // end Assimp
-
-#include "BlenderDNA.inl"
-
-#endif
diff --git a/3rdparty/assimp/code/BlenderDNA.inl b/3rdparty/assimp/code/BlenderDNA.inl
deleted file mode 100644
index c1be2546..00000000
--- a/3rdparty/assimp/code/BlenderDNA.inl
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderDNA.inl
- * @brief Blender `DNA` (file format specification embedded in
- * blend file itself) loader.
- */
-#ifndef INCLUDED_AI_BLEND_DNA_INL
-#define INCLUDED_AI_BLEND_DNA_INL
-
-namespace Assimp {
- namespace Blender {
-
-//--------------------------------------------------------------------------------
-const Field& Structure :: operator [] (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- if (it == indices.end()) {
- throw Error((Formatter::format(),
- "BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`"
- ));
- }
-
- return fields[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Field* Structure :: Get (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- return it == indices.end() ? NULL : &fields[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Field& Structure :: operator [] (const size_t i) const
-{
- if (i >= fields.size()) {
- throw Error((Formatter::format(),
- "BlendDNA: There is no field with index `",i,"` in structure `",name,"`"
- ));
- }
-
- return fields[i];
-}
-
-//--------------------------------------------------------------------------------
-template <typename T> boost::shared_ptr<ElemBase> Structure :: Allocate() const
-{
- return boost::shared_ptr<T>(new T());
-}
-
-//--------------------------------------------------------------------------------
-template <typename T> void Structure :: Convert(
- boost::shared_ptr<ElemBase> in,
- const FileDatabase& db) const
-{
- Convert<T> (*static_cast<T*> ( in.get() ),db);
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, typename T, size_t M>
-void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- const Structure& s = db.dna[f.type];
-
- // is the input actually an array?
- if (!(f.flags & FieldFlag_Array)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be an array of size ",M
- ));
- }
-
- db.reader->IncPtr(f.offset);
-
- // size conversions are always allowed, regardless of error_policy
- unsigned int i = 0;
- for (; i < std::min(f.array_sizes[0],M); ++i) {
- s.Convert(out[i],db);
- }
- for (; i < M; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
- }
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, typename T, size_t M, size_t N>
-void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- const Structure& s = db.dna[f.type];
-
- // is the input actually an array?
- if (!(f.flags & FieldFlag_Array)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be an array of size ",M,"*",N
- ));
- }
-
- db.reader->IncPtr(f.offset);
-
- // size conversions are always allowed, regardless of error_policy
- unsigned int i = 0;
- for (; i < std::min(f.array_sizes[0],M); ++i) {
- unsigned int j = 0;
- for (; j < std::min(f.array_sizes[1],N); ++j) {
- s.Convert(out[i][j],db);
- }
- for (; j < N; ++j) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i][j]);
- }
- }
- for (; i < M; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
- }
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, template <typename> class TOUT, typename T>
-void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- Pointer ptrval;
- const Field* f;
- try {
- f = &(*this)[name];
-
- // sanity check, should never happen if the genblenddna script is right
- if (!(f->flags & FieldFlag_Pointer)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be a pointer"));
- }
-
- db.reader->IncPtr(f->offset);
- Convert(ptrval,db);
- // actually it is meaningless on which Structure the Convert is called
- // because the `Pointer` argument triggers a special implementation.
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
-
- out.reset();
- return;
- }
-
- // resolve the pointer and load the corresponding structure
- ResolvePointer(out,ptrval,db,*f);
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, template <typename> class TOUT, typename T, size_t N>
-void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
- const FileDatabase& db) const
-{
- // XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- Pointer ptrval[N];
- const Field* f;
- try {
- f = &(*this)[name];
-
- // sanity check, should never happen if the genblenddna script is right
- if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be a pointer AND an array"));
- }
-
- db.reader->IncPtr(f->offset);
-
- size_t i = 0;
- for (; i < std::min(f->array_sizes[0],N); ++i) {
- Convert(ptrval[i],db);
- }
- for (; i < N; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(ptrval[i]);
- }
-
- // actually it is meaningless on which Structure the Convert is called
- // because the `Pointer` argument triggers a special implementation.
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- for (size_t i = 0; i < N; ++i) {
- out[i].reset();
- }
- return;
- }
- for (size_t i = 0; i < N; ++i) {
- // resolve the pointer and load the corresponding structure
- ResolvePointer(out[i],ptrval[i],db,*f);
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, typename T>
-void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- // find the structure definition pertaining to this field
- const Structure& s = db.dna[f.type];
-
- db.reader->IncPtr(f.offset);
- s.Convert(out,db);
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT, typename T>
-void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
-{
- out.reset();
- if (!ptrval.val) {
- return;
- }
- const Structure& s = db.dna[f.type];
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- // also determine the target type from the block header
- // and check if it matches the type which we expect.
- const Structure& ss = db.dna[block->dna_index];
- if (ss != s) {
- throw Error((Formatter::format(),"Expected target to be of type `",s.name,
- "` but seemingly it is a `",ss.name,"` instead"
- ));
- }
-
- // try to retrieve the object from the cache
- db.cache(out).get(s,out,ptrval);
- if (out) {
- return;
- }
-
- // seek to this location, but save the previous stream pointer.
- const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
- db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
- // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
- // I really ought to improve StreamReader to work with 64 bit indices exclusively.
-
- // continue conversion after allocating the required storage
- size_t num = block->size / ss.size;
- T* o = _allocate(out,num);
-
- // cache the object before we convert it to avoid cyclic recursion.
- db.cache(out).set(s,out,ptrval);
-
- for (size_t i = 0; i < num; ++i,++o) {
- s.Convert(*o,db);
- }
-
- db.reader->SetCurrentPos(pold);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- if (out) {
- ++db.stats().pointers_resolved;
- }
-#endif
-}
-
-//--------------------------------------------------------------------------------
-inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& /* f */ ) const
-{
- // Currently used exclusively by PackedFile::data to represent
- // a simple offset into the mapped BLEND file.
- out.reset();
- if (!ptrval.val) {
- return;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- out = boost::shared_ptr< FileOffset > (new FileOffset());
- out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
-}
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT, typename T>
-void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
-{
- // This is a function overload, not a template specialization. According to
- // the partial ordering rules, it should be selected by the compiler
- // for array-of-pointer inputs, i.e. Object::mats.
-
- out.reset();
- if (!ptrval.val) {
- return;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
- const size_t num = block->size / (db.i64bit?8:4);
-
- // keep the old stream position
- const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
- db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
-
- // allocate raw storage for the array
- out.resize(num);
- for (size_t i = 0; i< num; ++i) {
- Pointer val;
- Convert(val,db);
-
- // and resolve the pointees
- ResolvePointer(out[i],val,db,f);
- }
-
- db.reader->SetCurrentPos(pold);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
- const Pointer & ptrval,
- const FileDatabase& db,
- const Field& /* f */
-) const
-{
- // Special case when the data type needs to be determined at runtime.
- // Less secure than in the `strongly-typed` case.
-
- out.reset();
- if (!ptrval.val) {
- return;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- // determine the target type from the block header
- const Structure& s = db.dna[block->dna_index];
-
- // try to retrieve the object from the cache
- db.cache(out).get(s,out,ptrval);
- if (out) {
- return;
- }
-
- // seek to this location, but save the previous stream pointer.
- const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
- db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
- // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
- // I really ought to improve StreamReader to work with 64 bit indices exclusively.
-
- // continue conversion after allocating the required storage
- DNA::FactoryPair builders = db.dna.GetBlobToStructureConverter(s,db);
- if (!builders.first) {
- // this might happen if DNA::RegisterConverters hasn't been called so far
- // or if the target type is not contained in `our` DNA.
- out.reset();
- DefaultLogger::get()->warn((Formatter::format(),
- "Failed to find a converter for the `",s.name,"` structure"
- ));
- return;
- }
-
- // allocate the object hull
- out = (s.*builders.first)();
-
- // cache the object immediately to prevent infinite recursion in a
- // circular list with a single element (i.e. a self-referencing element).
- db.cache(out).set(s,out,ptrval);
-
- // and do the actual conversion
- (s.*builders.second)(out,db);
- db.reader->SetCurrentPos(pold);
-
- // store a pointer to the name string of the actual type
- // in the object itself. This allows the conversion code
- // to perform additional type checking.
- out->dna_type = s.name.c_str();
-
-
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().pointers_resolved;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrval, const FileDatabase& db) const
-{
- // the file blocks appear in list sorted by
- // with ascending base addresses so we can run a
- // binary search to locate the pointee quickly.
-
- // NOTE: Blender seems to distinguish between side-by-side
- // data (stored in the same data block) and far pointers,
- // which are only used for structures starting with an ID.
- // We don't need to make this distinction, our algorithm
- // works regardless where the data is stored.
- vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
- if (it == db.entries.end()) {
- // this is crucial, pointers may not be invalid.
- // this is either a corrupted file or an attempted attack.
- throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
- std::hex,ptrval.val,", no file block falls into this address range"
- ));
- }
- if (ptrval.val >= (*it).address.val + (*it).size) {
- throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
- std::hex,ptrval.val,", nearest file block starting at 0x",
- (*it).address.val," ends at 0x",
- (*it).address.val + (*it).size
- ));
- }
- return &*it;
-}
-
-// ------------------------------------------------------------------------------------------------
-// NOTE: The MSVC debugger keeps showing up this annoying `a cast to a smaller data type has
-// caused a loss of data`-warning. Avoid this warning by a masking with an appropriate bitmask.
-
-template <typename T> struct signless;
-template <> struct signless<char> {typedef unsigned char type;};
-template <> struct signless<short> {typedef unsigned short type;};
-template <> struct signless<int> {typedef unsigned int type;};
-
-template <typename T>
-struct static_cast_silent {
- template <typename V>
- T operator()(V in) {
- return static_cast<T>(in & static_cast<typename signless<T>::type>(-1));
- }
-};
-
-template <> struct static_cast_silent<float> {
- template <typename V> float operator()(V in) {
- return static_cast<float> (in);
- }
-};
-
-template <> struct static_cast_silent<double> {
- template <typename V> double operator()(V in) {
- return static_cast<double>(in);
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,const FileDatabase& db)
-{
- if (in.name == "int") {
- out = static_cast_silent<T>()(db.reader->GetU4());
- }
- else if (in.name == "short") {
- out = static_cast_silent<T>()(db.reader->GetU2());
- }
- else if (in.name == "char") {
- out = static_cast_silent<T>()(db.reader->GetU1());
- }
- else if (in.name == "float") {
- out = static_cast<T>(db.reader->GetF4());
- }
- else if (in.name == "double") {
- out = static_cast<T>(db.reader->GetF8());
- }
- else {
- throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const
-{
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const
-{
- // automatic rescaling from short to float and vice versa (seems to be used by normals)
- if (name == "float") {
- dest = static_cast<short>(db.reader->GetF4() * 32767.f);
- //db.reader->IncPtr(-4);
- return;
- }
- else if (name == "double") {
- dest = static_cast<short>(db.reader->GetF8() * 32767.);
- //db.reader->IncPtr(-8);
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const
-{
- // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
- if (name == "float") {
- dest = static_cast<char>(db.reader->GetF4() * 255.f);
- return;
- }
- else if (name == "double") {
- dest = static_cast<char>(db.reader->GetF8() * 255.f);
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const
-{
- // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
- if (name == "char") {
- dest = db.reader->GetI1() / 255.f;
- return;
- }
- // automatic rescaling from short to float and vice versa (used by normals)
- else if (name == "short") {
- dest = db.reader->GetI2() / 32767.f;
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const
-{
- if (name == "char") {
- dest = db.reader->GetI1() / 255.;
- return;
- }
- else if (name == "short") {
- dest = db.reader->GetI2() / 32767.;
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const
-{
- if (db.i64bit) {
- dest.val = db.reader->GetU8();
- //db.reader->IncPtr(-8);
- return;
- }
- dest.val = db.reader->GetU4();
- //db.reader->IncPtr(-4);
-}
-
-//--------------------------------------------------------------------------------
-const Structure& DNA :: operator [] (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- if (it == indices.end()) {
- throw Error((Formatter::format(),
- "BlendDNA: Did not find a structure named `",ss,"`"
- ));
- }
-
- return structures[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Structure* DNA :: Get (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- return it == indices.end() ? NULL : &structures[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Structure& DNA :: operator [] (const size_t i) const
-{
- if (i >= structures.size()) {
- throw Error((Formatter::format(),
- "BlendDNA: There is no structure with index `",i,"`"
- ));
- }
-
- return structures[i];
-}
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: get (
- const Structure& s,
- TOUT<T>& out,
- const Pointer& ptr
-) const {
-
- if (s.cache_idx == static_cast<size_t>(-1)) {
- s.cache_idx = db.next_cache_idx++;
- caches.resize(db.next_cache_idx);
- return;
- }
-
- typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
- if (it != caches[s.cache_idx].end()) {
- out = boost::static_pointer_cast<T>( (*it).second );
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().cache_hits;
-#endif
- }
- // otherwise, out remains untouched
-}
-
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: set (
- const Structure& s,
- const TOUT<T>& out,
- const Pointer& ptr
-) {
- if (s.cache_idx == static_cast<size_t>(-1)) {
- s.cache_idx = db.next_cache_idx++;
- caches.resize(db.next_cache_idx);
- }
- caches[s.cache_idx][ptr] = boost::static_pointer_cast<ElemBase>( out );
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().cached_objects;
-#endif
-}
-
-}}
-#endif
diff --git a/3rdparty/assimp/code/BlenderIntermediate.h b/3rdparty/assimp/code/BlenderIntermediate.h
deleted file mode 100644
index e8c969e9..00000000
--- a/3rdparty/assimp/code/BlenderIntermediate.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderIntermediate.h
- * @brief Internal utility structures for the BlenderLoader. It also serves
- * as master include file for the whole (internal) Blender subsystem.
- */
-#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
-#define INCLUDED_AI_BLEND_INTERMEDIATE_H
-
-#include "BlenderLoader.h"
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-#include "BlenderSceneGen.h"
-
-#define for_each(x,y) BOOST_FOREACH(x,y)
-
-namespace Assimp {
-namespace Blender {
-
- // --------------------------------------------------------------------
- /** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
- // --------------------------------------------------------------------
- template <template <typename,typename> class TCLASS, typename T>
- struct TempArray {
- typedef TCLASS< T*,std::allocator<T*> > mywrap;
-
- TempArray() {
- }
-
- ~TempArray () {
- for_each(T* elem, arr) {
- delete elem;
- }
- }
-
- void dismiss() {
- arr.clear();
- }
-
- mywrap* operator -> () {
- return &arr;
- }
-
- operator mywrap& () {
- return arr;
- }
-
- operator const mywrap& () const {
- return arr;
- }
-
- mywrap& get () {
- return arr;
- }
-
- const mywrap& get () const {
- return arr;
- }
-
- T* operator[] (size_t idx) const {
- return arr[idx];
- }
-
- T*& operator[] (size_t idx) {
- return arr[idx];
- }
-
- private:
- // no copy semantics
- void operator= (const TempArray&) {
- }
-
- TempArray(const TempArray& arr) {
- }
-
- private:
- mywrap arr;
- };
-
-#ifdef _MSC_VER
-# pragma warning(disable:4351)
-#endif
- // --------------------------------------------------------------------
- /** ConversionData acts as intermediate storage location for
- * the various ConvertXXX routines in BlenderImporter.*/
- // --------------------------------------------------------------------
- struct ConversionData
- {
- ConversionData(const FileDatabase& db)
- : sentinel_cnt()
- , next_texture()
- , db(db)
- {}
-
- std::set<const Object*> objects;
-
- TempArray <std::vector, aiMesh> meshes;
- TempArray <std::vector, aiCamera> cameras;
- TempArray <std::vector, aiLight> lights;
- TempArray <std::vector, aiMaterial> materials;
- TempArray <std::vector, aiTexture> textures;
-
- // set of all materials referenced by at least one mesh in the scene
- std::deque< boost::shared_ptr< Material > > materials_raw;
-
- // counter to name sentinel textures inserted as substitutes for procedural textures.
- unsigned int sentinel_cnt;
-
- // next texture ID for each texture type, respectively
- unsigned int next_texture[aiTextureType_UNKNOWN+1];
-
- // original file data
- const FileDatabase& db;
- };
-#ifdef _MSC_VER
-# pragma warning(default:4351)
-#endif
-
-// ------------------------------------------------------------------------------------------------
-inline const char* GetTextureTypeDisplayString(Tex::Type t)
-{
- switch (t) {
- case Tex::Type_CLOUDS : return "Clouds";
- case Tex::Type_WOOD : return "Wood";
- case Tex::Type_MARBLE : return "Marble";
- case Tex::Type_MAGIC : return "Magic";
- case Tex::Type_BLEND : return "Blend";
- case Tex::Type_STUCCI : return "Stucci";
- case Tex::Type_NOISE : return "Noise";
- case Tex::Type_PLUGIN : return "Plugin";
- case Tex::Type_MUSGRAVE : return "Musgrave";
- case Tex::Type_VORONOI : return "Voronoi";
- case Tex::Type_DISTNOISE : return "DistortedNoise";
- case Tex::Type_ENVMAP : return "EnvMap";
- case Tex::Type_IMAGE : return "Image";
- default:
- break;
- }
- return "<Unknown>";
-}
-
-} // ! Blender
-} // ! Assimp
-
-#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H
diff --git a/3rdparty/assimp/code/BlenderLoader.cpp b/3rdparty/assimp/code/BlenderLoader.cpp
deleted file mode 100644
index 47f3e58d..00000000
--- a/3rdparty/assimp/code/BlenderLoader.cpp
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderLoader.cpp
- * @brief Implementation of the Blender3D importer class.
- */
-#include "AssimpPCH.h"
-
-//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
-// Uncomment this to disable support for (gzip)compressed .BLEND files
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderIntermediate.h"
-#include "BlenderModifier.h"
-
-#include "StreamReader.h"
-#include "TinyFormatter.h"
-#include "MemoryIOWrapper.h"
-
-// zlib is needed for compressed blend files
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include "../contrib/zlib/zlib.h"
-# endif
-#endif
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-using namespace Assimp::Formatter;
-
-static const aiLoaderDesc blenderDesc = {
- "Blender 3D Importer \nhttp://www.blender3d.org",
- "Alexander Gessler <alexander.gessler@gmx.net>",
- "",
- "",
- aiLoaderFlags_SupportBinaryFlavour | aiLoaderFlags_Experimental,
- 0,
- 0,
- 2,
- 50
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BlenderImporter::BlenderImporter()
-: modifier_cache(new BlenderModifierShowcase())
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BlenderImporter::~BlenderImporter()
-{
- delete modifier_cache;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "blend") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- // note: this won't catch compressed files
- const char* tokens[] = {"BLENDER"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// List all extensions handled by this loader
-void BlenderImporter::GetExtensionList(std::set<std::string>& app)
-{
- app.insert("blend");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader registry entry
-const aiLoaderDesc& BlenderImporter::GetInfo () const
-{
- return blenderDesc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void BlenderImporter::SetupProperties(const Importer* /* pImp */)
-{
- // nothing to be done for the moment
-}
-
-struct free_it
-{
- free_it(void* free) : free(free) {}
- ~free_it() {
- ::free(this->free);
- }
-
- void* free;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void BlenderImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
- Bytef* dest = NULL;
- free_it free_it_really(dest);
-#endif
-
- FileDatabase file;
- boost::shared_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
- if (!stream) {
- ThrowException("Could not open file for reading");
- }
-
- char magic[8] = {0};
- stream->Read(magic,7,1);
- if (strcmp(magic,"BLENDER")) {
- // Check for presence of the gzip header. If yes, assume it is a
- // compressed blend file and try uncompressing it, else fail. This is to
- // avoid uncompressing random files which our loader might end up with.
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
- ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
-#else
-
- if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
- ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
- }
-
- LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
- if (magic[2] != 8) {
- ThrowException("Unsupported GZIP compression method");
- }
-
- // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
- stream->Seek(0L,aiOrigin_SET);
- boost::shared_ptr<StreamReaderLE> reader = boost::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
-
- // build a zlib stream
- z_stream zstream;
- zstream.opaque = Z_NULL;
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.data_type = Z_BINARY;
-
- // http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
- inflateInit2(&zstream, 16+MAX_WBITS);
-
- zstream.next_in = reinterpret_cast<Bytef*>( reader->GetPtr() );
- zstream.avail_in = reader->GetRemainingSize();
-
- size_t total = 0l;
-
- // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
-#define MYBLOCK 1024
- Bytef block[MYBLOCK];
- int ret;
- do {
- zstream.avail_out = MYBLOCK;
- zstream.next_out = block;
- ret = inflate(&zstream, Z_NO_FLUSH);
-
- if (ret != Z_STREAM_END && ret != Z_OK) {
- ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
- }
- const size_t have = MYBLOCK - zstream.avail_out;
- total += have;
- dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
- memcpy(dest + total - have,block,have);
- }
- while (ret != Z_STREAM_END);
-
- // terminate zlib
- inflateEnd(&zstream);
-
- // replace the input stream with a memory stream
- stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
-
- // .. and retry
- stream->Read(magic,7,1);
- if (strcmp(magic,"BLENDER")) {
- ThrowException("Found no BLENDER magic word in decompressed GZIP file");
- }
-#endif
- }
-
- file.i64bit = (stream->Read(magic,1,1),magic[0]=='-');
- file.little = (stream->Read(magic,1,1),magic[0]=='v');
-
- stream->Read(magic,3,1);
- magic[3] = '\0';
-
- LogInfo((format(),"Blender version is ",magic[0],".",magic+1,
- " (64bit: ",file.i64bit?"true":"false",
- ", little endian: ",file.little?"true":"false",")"
- ));
-
- ParseBlendFile(file,stream);
-
- Scene scene;
- ExtractScene(scene,file);
-
- ConvertBlendFile(pScene,scene,file);
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ParseBlendFile(FileDatabase& out, boost::shared_ptr<IOStream> stream)
-{
- out.reader = boost::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream,out.little));
-
- DNAParser dna_reader(out);
- const DNA* dna = NULL;
-
- out.entries.reserve(128); { // even small BLEND files tend to consist of many file blocks
- SectionParser parser(*out.reader.get(),out.i64bit);
-
- // first parse the file in search for the DNA and insert all other sections into the database
- while ((parser.Next(),1)) {
- const FileBlockHead& head = parser.GetCurrent();
-
- if (head.id == "ENDB") {
- break; // only valid end of the file
- }
- else if (head.id == "DNA1") {
- dna_reader.Parse();
- dna = &dna_reader.GetDNA();
- continue;
- }
-
- out.entries.push_back(head);
- }
- }
- if (!dna) {
- ThrowException("SDNA not found");
- }
-
- std::sort(out.entries.begin(),out.entries.end());
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
-{
- const FileBlockHead* block = NULL;
- std::map<std::string,size_t>::const_iterator it = file.dna.indices.find("Scene");
- if (it == file.dna.indices.end()) {
- ThrowException("There is no `Scene` structure record");
- }
-
- const Structure& ss = file.dna.structures[(*it).second];
-
- // we need a scene somewhere to start with.
- for_each(const FileBlockHead& bl,file.entries) {
- if (bl.id == "SC") {
- block = &bl;
- break;
- }
- }
-
- if (!block) {
- ThrowException("There is not a single `Scene` record to load");
- }
-
- file.reader->SetCurrentPos(block->start);
- ss.Convert(out,file);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- DefaultLogger::get()->info((format(),
- "(Stats) Fields read: " ,file.stats().fields_read,
- ", pointers resolved: " ,file.stats().pointers_resolved,
- ", cache hits: " ,file.stats().cache_hits,
- ", cached objects: " ,file.stats().cached_objects
- ));
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileDatabase& file)
-{
- ConversionData conv(file);
-
- // FIXME it must be possible to take the hierarchy directly from
- // the file. This is terrible. Here, we're first looking for
- // all objects which don't have parent objects at all -
- std::deque<const Object*> no_parents;
- for (boost::shared_ptr<Base> cur = boost::static_pointer_cast<Base> ( in.base.first ); cur; cur = cur->next) {
- if (cur->object) {
- if (!cur->object->parent) {
- no_parents.push_back(cur->object.get());
- }
- else conv.objects.insert(cur->object.get());
- }
- }
- for (boost::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
- if (cur->object) {
- if (cur->object->parent) {
- conv.objects.insert(cur->object.get());
- }
- }
- }
-
- if (no_parents.empty()) {
- ThrowException("Expected at least one object with no parent");
- }
-
- aiNode* root = out->mRootNode = new aiNode("<BlenderRoot>");
-
- root->mNumChildren = static_cast<unsigned int>(no_parents.size());
- root->mChildren = new aiNode*[root->mNumChildren]();
- for (unsigned int i = 0; i < root->mNumChildren; ++i) {
- root->mChildren[i] = ConvertNode(in, no_parents[i], conv);
- root->mChildren[i]->mParent = root;
- }
-
- BuildMaterials(conv);
-
- if (conv.meshes->size()) {
- out->mMeshes = new aiMesh*[out->mNumMeshes = static_cast<unsigned int>( conv.meshes->size() )];
- std::copy(conv.meshes->begin(),conv.meshes->end(),out->mMeshes);
- conv.meshes.dismiss();
- }
-
- if (conv.lights->size()) {
- out->mLights = new aiLight*[out->mNumLights = static_cast<unsigned int>( conv.lights->size() )];
- std::copy(conv.lights->begin(),conv.lights->end(),out->mLights);
- conv.lights.dismiss();
- }
-
- if (conv.cameras->size()) {
- out->mCameras = new aiCamera*[out->mNumCameras = static_cast<unsigned int>( conv.cameras->size() )];
- std::copy(conv.cameras->begin(),conv.cameras->end(),out->mCameras);
- conv.cameras.dismiss();
- }
-
- if (conv.materials->size()) {
- out->mMaterials = new aiMaterial*[out->mNumMaterials = static_cast<unsigned int>( conv.materials->size() )];
- std::copy(conv.materials->begin(),conv.materials->end(),out->mMaterials);
- conv.materials.dismiss();
- }
-
- if (conv.textures->size()) {
- out->mTextures = new aiTexture*[out->mNumTextures = static_cast<unsigned int>( conv.textures->size() )];
- std::copy(conv.textures->begin(),conv.textures->end(),out->mTextures);
- conv.textures.dismiss();
- }
-
- // acknowledge that the scene might come out incomplete
- // by Assimps definition of `complete`: blender scenes
- // can consist of thousands of cameras or lights with
- // not a single mesh between them.
- if (!out->mNumMeshes) {
- out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ResolveImage(MaterialHelper* out, const Material* /* mat */, const MTex* /*tex*/, const Image* img, ConversionData& conv_data)
-{
- // mat; tex; conv_data;
- aiString name;
-
- // check if the file contents are bundled with the BLEND file
- if (img->packedfile) {
- name.data[0] = '*';
- name.length = 1+ ASSIMP_itoa10(name.data+1,MAXLEN-1,conv_data.textures->size());
-
- conv_data.textures->push_back(new aiTexture());
- aiTexture* tex = conv_data.textures->back();
-
- // usually 'img->name' will be the original file name of the embedded textures,
- // so we can extract the file extension from it.
- const size_t nlen = strlen( img->name );
- const char* s = img->name+nlen, *e = s;
-
- while (s >= img->name && *s != '.')--s;
-
- tex->achFormatHint[0] = s+1>e ? '\0' : s[1];
- tex->achFormatHint[1] = s+2>e ? '\0' : s[2];
- tex->achFormatHint[2] = s+3>e ? '\0' : s[3];
- tex->achFormatHint[3] = '\0';
-
- // tex->mHeight = 0;
- tex->mWidth = img->packedfile->size;
- uint8_t* ch = new uint8_t[tex->mWidth];
-
- conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
- conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
-
- tex->pcData = reinterpret_cast<aiTexel*>(ch);
-
- LogInfo("Reading embedded texture, original file was "+std::string(img->name));
- }
- else {
- name = aiString( img->name );
- }
- out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
- conv_data.next_texture[aiTextureType_DIFFUSE]++)
- );
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::AddSentinelTexture(MaterialHelper* out, const Material* /*mat*/, const MTex* tex, ConversionData& conv_data)
-{
- // mat; tex; conv_data;
-
- aiString name;
- name.length = sprintf(name.data, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
- GetTextureTypeDisplayString(tex->tex->type)
- );
- out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
- conv_data.next_texture[aiTextureType_DIFFUSE]++)
- );
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ResolveTexture(MaterialHelper* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
-{
- const Tex* rtex = tex->tex.get();
- if (!rtex || !rtex->type) {
- return;
- }
-
- // We can't support most of the texture types because the're mostly procedural.
- // These are substituted by a dummy texture.
- const char* dispnam = "";
- switch( rtex->type )
- {
- // these are listed in blender's UI
- case Tex::Type_CLOUDS :
- case Tex::Type_WOOD :
- case Tex::Type_MARBLE :
- case Tex::Type_MAGIC :
- case Tex::Type_BLEND :
- case Tex::Type_STUCCI :
- case Tex::Type_NOISE :
- case Tex::Type_PLUGIN :
- case Tex::Type_MUSGRAVE :
- case Tex::Type_VORONOI :
- case Tex::Type_DISTNOISE :
- case Tex::Type_ENVMAP :
-
- // these do no appear in the UI, why?
- case Tex::Type_POINTDENSITY :
- case Tex::Type_VOXELDATA :
-
- LogWarn(std::string("Encountered a texture with an unsupported type: ")+dispnam);
- AddSentinelTexture(out, mat, tex, conv_data);
- break;
-
- case Tex::Type_IMAGE :
- if (!rtex->ima) {
- LogError("A texture claims to be an Image, but no image reference is given");
- break;
- }
- ResolveImage(out, mat, tex, rtex->ima.get(),conv_data);
- break;
-
- default:
- ai_assert(false);
- };
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::BuildMaterials(ConversionData& conv_data)
-{
- conv_data.materials->reserve(conv_data.materials_raw.size());
-
- // add a default material if necessary
- unsigned int index = static_cast<unsigned int>( -1 );
- for_each( aiMesh* mesh, conv_data.meshes.get() ) {
- if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
-
- if (index == static_cast<unsigned int>( -1 )) {
-
- // ok, we need to add a dedicated default material for some poor material-less meshes
- boost::shared_ptr<Material> p(new Material());
- strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
-
- p->r = p->g = p->b = 0.6f;
- p->specr = p->specg = p->specb = 0.6f;
- p->ambir = p->ambig = p->ambib = 0.0f;
- p->mirr = p->mirg = p->mirb = 0.0f;
- p->emit = 0.f;
- p->alpha = 0.f;
-
- // XXX add more / or add default c'tor to Material
-
- index = static_cast<unsigned int>( conv_data.materials_raw.size() );
- conv_data.materials_raw.push_back(p);
-
- LogInfo("Adding default material ...");
- }
- mesh->mMaterialIndex = index;
- }
- }
-
- for_each(boost::shared_ptr<Material> mat, conv_data.materials_raw) {
-
- // reset per material global counters
- for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
- conv_data.next_texture[i] = 0 ;
- }
-
- MaterialHelper* mout = new MaterialHelper();
- conv_data.materials->push_back(mout);
-
- // set material name
- aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
- mout->AddProperty(&name,AI_MATKEY_NAME);
-
-
- // basic material colors
- aiColor3D col(mat->r,mat->g,mat->b);
- if (mat->r || mat->g || mat->b ) {
-
- // Usually, zero diffuse color means no diffuse color at all in the equation - seemingly.
- // So we ommit this member to express this intent.
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_DIFFUSE);
- }
-
- col = aiColor3D(mat->specr,mat->specg,mat->specb);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_SPECULAR);
-
- col = aiColor3D(mat->ambir,mat->ambig,mat->ambib);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
-
- col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
-
- for (size_t i = 0; i < sizeof(mat->mtex) / sizeof(mat->mtex[0]); ++i) {
- if (!mat->mtex[i]) {
- continue;
- }
-
- ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
-{
- ai_assert(dt);
- if (strcmp(dt->dna_type,check)) {
- ThrowException((format(),
- "Expected object at ",std::hex,dt," to be of type `",check,
- "`, but it claims to be a `",dt->dna_type,"`instead"
- ));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::NotSupportedObjectType(const Object* obj, const char* type)
-{
- LogWarn((format(), "Object `",obj->id.name,"` - type is unsupported: `",type, "`, skipping" ));
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ConvertMesh(const Scene& /* in */, const Object* /* obj */, const Mesh* mesh,
- ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
- )
-{
- typedef std::pair<const int,size_t> MyPair;
- if (!mesh->totface || !mesh->totvert) {
- return;
- }
-
- // some sanity checks
- if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ){
- ThrowException("Number of faces is larger than the corresponding array");
- }
-
- if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
- ThrowException("Number of vertices is larger than the corresponding array");
- }
-
- // collect per-submesh numbers
- std::map<int,size_t> per_mat;
- for (int i = 0; i < mesh->totface; ++i) {
-
- const MFace& mf = mesh->mface[i];
- per_mat[ mf.mat_nr ]++;
- }
-
- // ... and allocate the corresponding meshes
- const size_t old = temp->size();
- temp->reserve(temp->size() + per_mat.size());
-
- std::map<size_t,size_t> mat_num_to_mesh_idx;
- for_each(MyPair& it, per_mat) {
-
- mat_num_to_mesh_idx[it.first] = temp->size();
- temp->push_back(new aiMesh());
-
- aiMesh* out = temp->back();
- out->mVertices = new aiVector3D[it.second*4];
- out->mNormals = new aiVector3D[it.second*4];
-
- //out->mNumFaces = 0
- //out->mNumVertices = 0
- out->mFaces = new aiFace[it.second]();
-
- // all submeshes created from this mesh are named equally. this allows
- // curious users to recover the original adjacency.
- out->mName = aiString(mesh->id.name+2);
- // skip over the name prefix 'ME'
-
- // resolve the material reference and add this material to the set of
- // output materials. The (temporary) material index is the index
- // of the material entry within the list of resolved materials.
- if (mesh->mat) {
-
- if (static_cast<size_t> ( it.first ) >= mesh->mat.size() ) {
- ThrowException("Material index is out of range");
- }
-
- boost::shared_ptr<Material> mat = mesh->mat[it.first];
- const std::deque< boost::shared_ptr<Material> >::iterator has = std::find(
- conv_data.materials_raw.begin(),
- conv_data.materials_raw.end(),mat
- );
-
- if (has != conv_data.materials_raw.end()) {
- out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
- }
- else {
- out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
- conv_data.materials_raw.push_back(mat);
- }
- }
- else out->mMaterialIndex = static_cast<unsigned int>( -1 );
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
-
- const MFace& mf = mesh->mface[i];
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
- aiFace& f = out->mFaces[out->mNumFaces++];
-
- f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
- aiVector3D* vo = out->mVertices + out->mNumVertices;
- aiVector3D* vn = out->mNormals + out->mNumVertices;
-
- // XXX we can't fold this easily, because we are restricted
- // to the member names from the BLEND file (v1,v2,v3,v4)
- // which are assigned by the genblenddna.py script and
- // cannot be changed without breaking the entire
- // import process.
-
- if (mf.v1 >= mesh->totvert) {
- ThrowException("Vertex index v1 out of range");
- }
- const MVert* v = &mesh->mvert[mf.v1];
- vo->x = v->co[0];
- vo->y = v->co[1];
- vo->z = v->co[2];
- vn->x = v->no[0];
- vn->y = v->no[1];
- vn->z = v->no[2];
- f.mIndices[0] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- // if (f.mNumIndices >= 2) {
- if (mf.v2 >= mesh->totvert) {
- ThrowException("Vertex index v2 out of range");
- }
- v = &mesh->mvert[mf.v2];
- vo->x = v->co[0];
- vo->y = v->co[1];
- vo->z = v->co[2];
- vn->x = v->no[0];
- vn->y = v->no[1];
- vn->z = v->no[2];
- f.mIndices[1] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- if (mf.v3 >= mesh->totvert) {
- ThrowException("Vertex index v3 out of range");
- }
- // if (f.mNumIndices >= 3) {
- v = &mesh->mvert[mf.v3];
- vo->x = v->co[0];
- vo->y = v->co[1];
- vo->z = v->co[2];
- vn->x = v->no[0];
- vn->y = v->no[1];
- vn->z = v->no[2];
- f.mIndices[2] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- if (mf.v4 >= mesh->totvert) {
- ThrowException("Vertex index v4 out of range");
- }
- // if (f.mNumIndices >= 4) {
- if (mf.v4) {
- v = &mesh->mvert[mf.v4];
- vo->x = v->co[0];
- vo->y = v->co[1];
- vo->z = v->co[2];
- vn->x = v->no[0];
- vn->y = v->no[1];
- vn->z = v->no[2];
- f.mIndices[3] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
- else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
-
- // }
- // }
- // }
- }
-
- // collect texture coordinates, they're stored in a separate per-face buffer
- if (mesh->mtface) {
- if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
- ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
- const MTFace* v = &mesh->mtface[i];
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
- for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
- vo->x = v->uv[i][0];
- vo->y = v->uv[i][1];
- }
- }
- }
-
- // collect texture coordinates, old-style (marked as deprecated in current blender sources)
- if (mesh->tface) {
- if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
- ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
- const TFace* v = &mesh->tface[i];
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
- for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
- vo->x = v->uv[i][0];
- vo->y = v->uv[i][1];
- }
- }
- }
-
- // collect vertex colors, stored separately as well
- if (mesh->mcol) {
- if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
- ThrowException("Number of faces is larger than the corresponding color face array");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiColor4D* vo = &out->mColors[0][out->mNumVertices];
- for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
- const MCol* col = &mesh->mcol[(i<<2)+n];
-
- vo->r = col->r;
- vo->g = col->g;
- vo->b = col->b;
- vo->a = col->a;
- }
- for (unsigned int n = f.mNumIndices; n < 4; ++n) {};
- }
- }
-
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiCamera* BlenderImporter::ConvertCamera(const Scene& /* in */, const Object* /* obj */, const Camera* /* mesh */, ConversionData& /* conv_data */)
-{
- ScopeGuard<aiCamera> out(new aiCamera());
-
- return NULL ; //out.dismiss();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiLight* BlenderImporter::ConvertLight(const Scene& /* in */, const Object* /* obj */, const Lamp* /* mesh */, ConversionData& /* conv_data */)
-{
- ScopeGuard<aiLight> out(new aiLight());
-
- return NULL ; //out.dismiss();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data)
-{
- std::deque<const Object*> children;
- for (std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
- const Object* object = *it;
- if (object->parent.get() == obj) {
- children.push_back(object);
-
- conv_data.objects.erase(it++);
- continue;
- }
- ++it;
- }
-
- ScopeGuard<aiNode> node(new aiNode(obj->id.name+2)); // skip over the name prefix 'OB'
- if (obj->data) {
- switch (obj->type)
- {
- case Object :: Type_EMPTY:
- break; // do nothing
-
-
- // supported object types
- case Object :: Type_MESH: {
- const size_t old = conv_data.meshes->size();
-
- CheckActualType(obj->data.get(),"Mesh");
- ConvertMesh(in,obj,static_cast<const Mesh*>(obj->data.get()),conv_data,conv_data.meshes);
-
- if (conv_data.meshes->size() > old) {
- node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
- for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
- node->mMeshes[i] = i + old;
- }
- }}
- break;
- case Object :: Type_LAMP: {
- CheckActualType(obj->data.get(),"Lamp");
- aiLight* mesh = ConvertLight(in,obj,static_cast<const Lamp*>(
- obj->data.get()),conv_data);
-
- if (mesh) {
- conv_data.lights->push_back(mesh);
- }}
- break;
- case Object :: Type_CAMERA: {
- CheckActualType(obj->data.get(),"Camera");
- aiCamera* mesh = ConvertCamera(in,obj,static_cast<const Camera*>(
- obj->data.get()),conv_data);
-
- if (mesh) {
- conv_data.cameras->push_back(mesh);
- }}
- break;
-
-
- // unsupported object types / log, but do not break
- case Object :: Type_CURVE:
- NotSupportedObjectType(obj,"Curve");
- break;
- case Object :: Type_SURF:
- NotSupportedObjectType(obj,"Surface");
- break;
- case Object :: Type_FONT:
- NotSupportedObjectType(obj,"Font");
- break;
- case Object :: Type_MBALL:
- NotSupportedObjectType(obj,"MetaBall");
- break;
- case Object :: Type_WAVE:
- NotSupportedObjectType(obj,"Wave");
- break;
- case Object :: Type_LATTICE:
- NotSupportedObjectType(obj,"Lattice");
- break;
-
- // invalid or unknown type
- default:
- break;
- }
- }
-
- for (unsigned int x = 0; x < 4; ++x) {
- for (unsigned int y = 0; y < 4; ++y) {
- node->mTransformation[y][x] = obj->parentinv[x][y];
- }
- }
-
- aiMatrix4x4 m;
- for (unsigned int x = 0; x < 4; ++x) {
- for (unsigned int y = 0; y < 4; ++y) {
- m[y][x] = obj->obmat[x][y];
- }
- }
-
- node->mTransformation = m*node->mTransformation;
-
- if (children.size()) {
- node->mNumChildren = static_cast<unsigned int>(children.size());
- aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
- for_each (const Object* nobj,children) {
- *nd = ConvertNode(in,nobj,conv_data);
- (*nd++)->mParent = node;
- }
- }
-
- // apply modifiers
- modifier_cache->ApplyModifiers(*node,conv_data,in,*obj);
-
- return node.dismiss();
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void BlenderImporter::ThrowException(const std::string& msg)
-{
- throw DeadlyImportError("BLEND: "+msg);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void BlenderImporter::LogWarn(const Formatter::format& message) {
- DefaultLogger::get()->warn(std::string("BLEND: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void BlenderImporter::LogError(const Formatter::format& message) {
- DefaultLogger::get()->error(std::string("BLEND: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void BlenderImporter::LogInfo(const Formatter::format& message) {
- DefaultLogger::get()->info(std::string("BLEND: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void BlenderImporter::LogDebug(const Formatter::format& message) {
- DefaultLogger::get()->debug(std::string("BLEND: ")+=message);
-}
-
-#endif
diff --git a/3rdparty/assimp/code/BlenderLoader.h b/3rdparty/assimp/code/BlenderLoader.h
deleted file mode 100644
index 0439b9ab..00000000
--- a/3rdparty/assimp/code/BlenderLoader.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderLoader.h
- * @brief Declaration of the Blender 3D (*.blend) importer class.
- */
-#ifndef INCLUDED_AI_BLEND_LOADER_H
-#define INCLUDED_AI_BLEND_LOADER_H
-
-#include "BaseImporter.h"
-namespace Assimp {
-
- // TinyFormatter.h
- namespace Formatter {
- template <typename T,typename TR, typename A> class basic_formatter;
- typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
- }
-
- // BlenderDNA.h
- namespace Blender {
- class FileDatabase;
- struct ElemBase;
- }
-
- // BlenderScene.h
- namespace Blender {
- struct Scene;
- struct Object;
- struct Mesh;
- struct Camera;
- struct Lamp;
- struct MTex;
- struct Image;
- struct Material;
- }
-
- // BlenderIntermediate.h
- namespace Blender {
- struct ConversionData;
- template <template <typename,typename> class TCLASS, typename T> struct TempArray;
- }
-
- // BlenderModifier.h
- namespace Blender {
- class BlenderModifierShowcase;
- class BlenderModifier;
- }
-
-enum aiLoaderFlags
-{
- aiLoaderFlags_SupportAsciiFlavour = 0x1,
- aiLoaderFlags_SupportBinaryFlavour = 0x2,
- aiLoaderFlags_SupportCompressedFlavour = 0x4,
-
- aiLoaderFlags_LimitedSupport = 0x8,
-
- aiLoaderFlags_Experimental = 0x10,
- aiLoaderFlags_Testing = 0x20,
- aiLoaderFlags_Production = 0x40,
-};
-
-struct aiLoaderDesc
-{
- const char* mName;
- const char* mAuthor;
- const char* mMaintainer;
- const char* mComments;
- unsigned int mFlags;
-
- unsigned int mMinMajor;
- unsigned int mMinMinor;
- unsigned int mMaxMajor;
- unsigned int mMaxMinor;
-};
-
-
-// -------------------------------------------------------------------------------------------
-/** Load blenders official binary format. The actual file structure (the `DNA` how they
- * call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
- * conversion from intermediate format to aiScene. */
-// -------------------------------------------------------------------------------------------
-class BlenderImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
-
- /** Constructor to be privately used by Importer */
- BlenderImporter();
-
- /** Destructor, private as well */
- ~BlenderImporter();
-
-public:
-
- // --------------------
- bool CanRead( const std::string& pFile,
- IOSystem* pIOHandler,
- bool checkSig
- ) const;
-
-protected:
-
- // --------------------
- const aiLoaderDesc& GetInfo () const;
-
- // --------------------
- void GetExtensionList(std::set<std::string>& app);
-
- // --------------------
- void SetupProperties(const Importer* pImp);
-
- // --------------------
- void InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler
- );
-
- // --------------------
- void ParseBlendFile(Blender::FileDatabase& out,
- boost::shared_ptr<IOStream> stream
- );
-
- // --------------------
- void ExtractScene(Blender::Scene& out,
- const Blender::FileDatabase& file
- );
-
- // --------------------
- void ConvertBlendFile(aiScene* out,
- const Blender::Scene& in,
- const Blender::FileDatabase& file
- );
-
-private:
-
- // --------------------
- aiNode* ConvertNode(const Blender::Scene& in,
- const Blender::Object* obj,
- Blender::ConversionData& conv_info
- );
-
- // --------------------
- void ConvertMesh(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Mesh* mesh,
- Blender::ConversionData& conv_data,
- Blender::TempArray<std::vector,aiMesh>& temp
- );
-
- // --------------------
- aiLight* ConvertLight(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Lamp* mesh,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- aiCamera* ConvertCamera(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Camera* mesh,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- void BuildMaterials(
- Blender::ConversionData& conv_data
- ) ;
-
- // --------------------
- void ResolveTexture(
- MaterialHelper* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- void ResolveImage(
- MaterialHelper* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- const Blender::Image* img,
- Blender::ConversionData& conv_data
- );
-
- void AddSentinelTexture(
- MaterialHelper* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- Blender::ConversionData& conv_data
- );
-
-private: // static stuff, mostly logging and error reporting.
-
- // --------------------
- static void CheckActualType(const Blender::ElemBase* dt,
- const char* check
- );
-
- // --------------------
- static void NotSupportedObjectType(const Blender::Object* obj,
- const char* type
- );
-
- // -------------------------------------------------------------------
- /** Prepend 'BLEND: ' and throw msg.*/
- static void ThrowException(const std::string& msg);
-
- // -------------------------------------------------------------------
- /** @defgroup blog Prepend 'BLEND: ' and write @c message to log.*/
- static void LogWarn (const Formatter::format& message); //! @ingroup blog
- static void LogError (const Formatter::format& message); //! @ingroup blog
- static void LogInfo (const Formatter::format& message); //! @ingroup blog
- static void LogDebug (const Formatter::format& message); //! @ingroup blog
-
-private:
-
- Blender::BlenderModifierShowcase* modifier_cache;
-
-}; // !class BlenderImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/BlenderModifier.cpp b/3rdparty/assimp/code/BlenderModifier.cpp
deleted file mode 100644
index eb3795a8..00000000
--- a/3rdparty/assimp/code/BlenderModifier.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderModifier.cpp
- * @brief Implementation of some blender modifiers (i.e subdivision, mirror).
- */
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-#include "BlenderModifier.h"
-#include "SceneCombiner.h"
-#include "Subdivision.h"
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-
-template <typename T> BlenderModifier* god() {
- return new T();
-}
-
-// add all available modifiers here
-typedef BlenderModifier* (*fpCreateModifier)();
-static const fpCreateModifier creators[] = {
- &god<BlenderModifier_Mirror>,
- &god<BlenderModifier_Subdivision>,
-
- NULL // sentinel
-};
-
-// ------------------------------------------------------------------------------------------------
-// just testing out some new macros to simplify logging
-#define ASSIMP_LOG_WARN_F(string,...)\
- DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_ERROR_F(string,...)\
- DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_DEBUG_F(string,...)\
- DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_INFO_F(string,...)\
- DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
-
-
-#define ASSIMP_LOG_WARN(string)\
- DefaultLogger::get()->warn(string)
-
-#define ASSIMP_LOG_ERROR(string)\
- DefaultLogger::get()->error(string)
-
-#define ASSIMP_LOG_DEBUG(string)\
- DefaultLogger::get()->debug(string)
-
-#define ASSIMP_LOG_INFO(string)\
- DefaultLogger::get()->info(string)
-
-
-// ------------------------------------------------------------------------------------------------
-struct SharedModifierData : ElemBase
-{
- ModifierData modifier;
-};
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
-{
- size_t cnt = 0u, ful = 0u;
-
- // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
- // we're allowed to dereference the pointers without risking to crash. We might still be
- // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
- // structures is at offset sizeof(vftable) with no padding.
- const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
- for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
- ai_assert(cur->dna_type);
-
- const Structure* s = conv_data.db.dna.Get( cur->dna_type );
- if (!s) {
- ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
- continue;
- }
-
- // this is a common trait of all XXXMirrorData structures in BlenderDNA
- const Field* f = s->Get("modifier");
- if (!f || f->offset != 0) {
- ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
- continue;
- }
-
- s = conv_data.db.dna.Get( f->type );
- if (!s || s->name != "ModifierData") {
- ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
- continue;
- }
-
- // now, we can be sure that we should be fine to dereference *cur* as
- // ModifierData (with the above note).
- const ModifierData& dat = cur->modifier;
-
- const fpCreateModifier* curgod = creators;
- std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
-
- for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
- if (curmod == endmod) {
- cached_modifiers->push_back((*curgod)());
-
- endmod = cached_modifiers->end();
- curmod = endmod-1;
- }
-
- BlenderModifier* const modifier = *curmod;
- if (modifier->IsActive(dat)) {
- modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
- cnt++;
-
- curgod = NULL;
- break;
- }
- }
- if (curgod) {
- ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
- }
- }
-
- // Even though we managed to resolve some or all of the modifiers on this
- // object, we still can't say whether our modifier implementations were
- // able to fully do their job.
- if (ful) {
- ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
- "`, check log messages above for errors");
- }
-}
-
-
-
-// ------------------------------------------------------------------------------------------------
-bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
-{
- return modin.type == ModifierData::eModifierType_Mirror;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
- const Scene& /* in */,
- const Object& orig_object )
-{
- // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
- const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
- ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
-
- // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
-
- // take all input meshes and clone them
- for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
- aiMesh* mesh;
- SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
-
- const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
- const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
- const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
-
- if (mir.mirror_ob) {
- const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mVertices[i];
-
- v.x = center.x + xs*(center.x - v.x);
- v.y = center.y + ys*(center.y - v.y);
- v.z = center.z + zs*(center.z - v.z);
- }
- }
- else {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mVertices[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mNormals) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mNormals[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mTangents) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mTangents[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mBitangents) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mBitangents[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
- const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
-
- for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mTextureCoords[n][i];
- v.x *= us;v.y *= vs;
- }
- }
-
- conv_data.meshes->push_back(mesh);
- }
- unsigned int* nind = new unsigned int[out.mNumMeshes*2];
-
- std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
- std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
- std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
-
- delete[] out.mMeshes;
- out.mMeshes = nind;
- out.mNumMeshes *= 2;
-
- ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
- orig_object.id.name,"`");
-}
-
-
-
-
-// ------------------------------------------------------------------------------------------------
-bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
-{
- return modin.type == ModifierData::eModifierType_Subsurf;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
- const Scene& /* in */,
- const Object& orig_object )
-{
- // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
- const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
- ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
-
- Subdivider::Algorithm algo;
- switch (mir.subdivType)
- {
- case SubsurfModifierData::TYPE_CatmullClarke:
- algo = Subdivider::CATMULL_CLARKE;
- break;
-
- case SubsurfModifierData::TYPE_Simple:
- ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
- algo = Subdivider::CATMULL_CLARKE;
- break;
-
- default:
- ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
- return;
- };
-
- boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
- ai_assert(subd);
-
- aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
- boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
-
- subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
- std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
-
- ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
- orig_object.id.name,"`");
-}
-
-#endif
diff --git a/3rdparty/assimp/code/BlenderModifier.h b/3rdparty/assimp/code/BlenderModifier.h
deleted file mode 100644
index 43e503fb..00000000
--- a/3rdparty/assimp/code/BlenderModifier.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderModifier.h
- * @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
- */
-#ifndef INCLUDED_AI_BLEND_MODIFIER_H
-#define INCLUDED_AI_BLEND_MODIFIER_H
-
-#include "BlenderIntermediate.h"
-#include "TinyFormatter.h"
-namespace Assimp {
- namespace Blender {
-
-// -------------------------------------------------------------------------------------------
-/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
- * they should be stateless and not try to cache model data. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier
-{
-public:
-
- virtual ~BlenderModifier() {
- }
-
-public:
-
- // --------------------
- /** Check if *this* modifier is active, given a ModifierData& block.*/
- virtual bool IsActive( const ModifierData& /* modin */) {
- return false;
- }
-
- // --------------------
- /** Apply the modifier to a given output node. The original data used
- * to construct the node is given as well. Not called unless IsActive()
- * was called and gave positive response. */
- virtual void DoIt(aiNode& /* out */,
- ConversionData& /* conv_data */,
- const ElemBase& orig_modifier,
- const Scene& /* in */,
- const Object& /* orig_object */
- ) {
- DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
- return;
- }
-};
-
-
-// -------------------------------------------------------------------------------------------
-/** Manage all known modifiers and instance and apply them if necessary */
-// -------------------------------------------------------------------------------------------
-class BlenderModifierShowcase
-{
-public:
-
- // --------------------
- /** Apply all requested modifiers provided we support them. */
- void ApplyModifiers(aiNode& out,
- ConversionData& conv_data,
- const Scene& in,
- const Object& orig_object
- );
-
-private:
-
- TempArray< std::vector,BlenderModifier > cached_modifiers;
-};
-
-
-
-
-
-// MODIFIERS
-
-
-
-// -------------------------------------------------------------------------------------------
-/** Mirror modifier. Status: implemented. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier_Mirror : public BlenderModifier
-{
-public:
-
- // --------------------
- virtual bool IsActive( const ModifierData& modin);
-
- // --------------------
- virtual void DoIt(aiNode& out,
- ConversionData& conv_data,
- const ElemBase& orig_modifier,
- const Scene& in,
- const Object& orig_object
- ) ;
-};
-
-// -------------------------------------------------------------------------------------------
-/** Subdivision modifier. Status: dummy. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier_Subdivision : public BlenderModifier
-{
-public:
-
- // --------------------
- virtual bool IsActive( const ModifierData& modin);
-
- // --------------------
- virtual void DoIt(aiNode& out,
- ConversionData& conv_data,
- const ElemBase& orig_modifier,
- const Scene& in,
- const Object& orig_object
- ) ;
-};
-
-
-}}
-#endif // !INCLUDED_AI_BLEND_MODIFIER_H
diff --git a/3rdparty/assimp/code/BlenderScene.cpp b/3rdparty/assimp/code/BlenderScene.cpp
deleted file mode 100644
index cfb97d2e..00000000
--- a/3rdparty/assimp/code/BlenderScene.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderScene.cpp
- * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
- */
-#include "AssimpPCH.h"
-#ifndef AI_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-#include "BlenderSceneGen.h"
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Object> (
- Object& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
- ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
- ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
- ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.track,"*track",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy,"*proxy",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_from,"*proxy_from",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_group,"*proxy_group",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.dup_group,"*dup_group",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
- ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Group> (
- Group& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MTex> (
- MTex& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
- ReadField<ErrorPolicy_Igno>((int&)dest.projx,"projx",db);
- ReadField<ErrorPolicy_Igno>((int&)dest.projy,"projy",db);
- ReadField<ErrorPolicy_Igno>((int&)dest.projz,"projz",db);
- ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
- ReadField<ErrorPolicy_Igno>(dest.rot,"rot",db);
- ReadField<ErrorPolicy_Igno>(dest.texflag,"texflag",db);
- ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
- ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
- ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
- ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
- ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
- ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
- ReadField<ErrorPolicy_Igno>(dest.difffac,"difffac",db);
- ReadField<ErrorPolicy_Igno>(dest.specfac,"specfac",db);
- ReadField<ErrorPolicy_Igno>(dest.emitfac,"emitfac",db);
- ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<TFace> (
- TFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.col,"col",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
- ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<SubsurfModifierData> (
- SubsurfModifierData& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
- ReadField<ErrorPolicy_Igno>(dest.subdivType,"subdivType",db);
- ReadField<ErrorPolicy_Igno>(dest.levels,"levels",db);
- ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
- ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MFace> (
- MFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
- ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
- ReadField<ErrorPolicy_Fail>(dest.v3,"v3",db);
- ReadField<ErrorPolicy_Fail>(dest.v4,"v4",db);
- ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Lamp> (
- Lamp& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
- ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
- ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
- ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
- ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
- ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
- ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
- ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
- ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
- ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
- ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
- ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MDeformWeight> (
- MDeformWeight& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
- ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<PackedFile> (
- PackedFile& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Warn>(dest.size,"size",db);
- ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Base> (
- Base& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.object,"*object",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MTFace> (
- MTFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
- ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Material> (
- Material& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.specr,"specr",db);
- ReadField<ErrorPolicy_Warn>(dest.specg,"specg",db);
- ReadField<ErrorPolicy_Warn>(dest.specb,"specb",db);
- ReadField<ErrorPolicy_Warn>(dest.ambir,"ambir",db);
- ReadField<ErrorPolicy_Warn>(dest.ambig,"ambig",db);
- ReadField<ErrorPolicy_Warn>(dest.ambib,"ambib",db);
- ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
- ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
- ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
- ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
- ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
- ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
- ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
- ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
- ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
- ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
- ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
- ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Mesh> (
- Mesh& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Fail>(dest.totface,"totface",db);
- ReadField<ErrorPolicy_Fail>(dest.totedge,"totedge",db);
- ReadField<ErrorPolicy_Fail>(dest.totvert,"totvert",db);
- ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db);
- ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db);
- ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db);
- ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.mface,"*mface",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.mvert,"*mvert",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.medge,"*medge",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MDeformVert> (
- MDeformVert& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
- ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<World> (
- World& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MVert> (
- MVert& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray<ErrorPolicy_Fail>(dest.co,"co",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
- ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MEdge> (
- MEdge& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
- ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
- ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
- ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<GroupObject> (
- GroupObject& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Fail>(dest.prev,"*prev",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<ListBase> (
- ListBase& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<ModifierData> (
- ModifierData& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
- ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<ID> (
- ID& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MCol> (
- MCol& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.r,"r",db);
- ReadField<ErrorPolicy_Fail>(dest.g,"g",db);
- ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
- ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Image> (
- Image& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
- ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.source,"source",db);
- ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
- ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
- ReadField<ErrorPolicy_Igno>(dest.pad1,"pad1",db);
- ReadField<ErrorPolicy_Igno>(dest.lastframe,"lastframe",db);
- ReadField<ErrorPolicy_Igno>(dest.tpageflag,"tpageflag",db);
- ReadField<ErrorPolicy_Igno>(dest.totbind,"totbind",db);
- ReadField<ErrorPolicy_Igno>(dest.xrep,"xrep",db);
- ReadField<ErrorPolicy_Igno>(dest.yrep,"yrep",db);
- ReadField<ErrorPolicy_Igno>(dest.twsta,"twsta",db);
- ReadField<ErrorPolicy_Igno>(dest.twend,"twend",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.packedfile,"*packedfile",db);
- ReadField<ErrorPolicy_Igno>(dest.lastupdate,"lastupdate",db);
- ReadField<ErrorPolicy_Igno>(dest.lastused,"lastused",db);
- ReadField<ErrorPolicy_Igno>(dest.animspeed,"animspeed",db);
- ReadField<ErrorPolicy_Igno>(dest.gen_x,"gen_x",db);
- ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db);
- ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Scene> (
- Scene& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.camera,"*camera",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.world,"*world",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
- ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Library> (
- Library& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Tex> (
- Tex& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Camera> (
- Camera& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
- ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
- ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MirrorModifierData> (
- MirrorModifierData& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
- ReadField<ErrorPolicy_Igno>(dest.axis,"axis",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-void DNA::RegisterConverters() {
-
- converters["Object"] = DNA::FactoryPair( &Structure::Allocate<Object>, &Structure::Convert<Object> );
- converters["Group"] = DNA::FactoryPair( &Structure::Allocate<Group>, &Structure::Convert<Group> );
- converters["MTex"] = DNA::FactoryPair( &Structure::Allocate<MTex>, &Structure::Convert<MTex> );
- converters["TFace"] = DNA::FactoryPair( &Structure::Allocate<TFace>, &Structure::Convert<TFace> );
- converters["SubsurfModifierData"] = DNA::FactoryPair( &Structure::Allocate<SubsurfModifierData>, &Structure::Convert<SubsurfModifierData> );
- converters["MFace"] = DNA::FactoryPair( &Structure::Allocate<MFace>, &Structure::Convert<MFace> );
- converters["Lamp"] = DNA::FactoryPair( &Structure::Allocate<Lamp>, &Structure::Convert<Lamp> );
- converters["MDeformWeight"] = DNA::FactoryPair( &Structure::Allocate<MDeformWeight>, &Structure::Convert<MDeformWeight> );
- converters["PackedFile"] = DNA::FactoryPair( &Structure::Allocate<PackedFile>, &Structure::Convert<PackedFile> );
- converters["Base"] = DNA::FactoryPair( &Structure::Allocate<Base>, &Structure::Convert<Base> );
- converters["MTFace"] = DNA::FactoryPair( &Structure::Allocate<MTFace>, &Structure::Convert<MTFace> );
- converters["Material"] = DNA::FactoryPair( &Structure::Allocate<Material>, &Structure::Convert<Material> );
- converters["Mesh"] = DNA::FactoryPair( &Structure::Allocate<Mesh>, &Structure::Convert<Mesh> );
- converters["MDeformVert"] = DNA::FactoryPair( &Structure::Allocate<MDeformVert>, &Structure::Convert<MDeformVert> );
- converters["World"] = DNA::FactoryPair( &Structure::Allocate<World>, &Structure::Convert<World> );
- converters["MVert"] = DNA::FactoryPair( &Structure::Allocate<MVert>, &Structure::Convert<MVert> );
- converters["MEdge"] = DNA::FactoryPair( &Structure::Allocate<MEdge>, &Structure::Convert<MEdge> );
- converters["GroupObject"] = DNA::FactoryPair( &Structure::Allocate<GroupObject>, &Structure::Convert<GroupObject> );
- converters["ListBase"] = DNA::FactoryPair( &Structure::Allocate<ListBase>, &Structure::Convert<ListBase> );
- converters["ModifierData"] = DNA::FactoryPair( &Structure::Allocate<ModifierData>, &Structure::Convert<ModifierData> );
- converters["ID"] = DNA::FactoryPair( &Structure::Allocate<ID>, &Structure::Convert<ID> );
- converters["MCol"] = DNA::FactoryPair( &Structure::Allocate<MCol>, &Structure::Convert<MCol> );
- converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
- converters["Scene"] = DNA::FactoryPair( &Structure::Allocate<Scene>, &Structure::Convert<Scene> );
- converters["Library"] = DNA::FactoryPair( &Structure::Allocate<Library>, &Structure::Convert<Library> );
- converters["Tex"] = DNA::FactoryPair( &Structure::Allocate<Tex>, &Structure::Convert<Tex> );
- converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
- converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
-}
-
-
-#endif
diff --git a/3rdparty/assimp/code/BlenderScene.h b/3rdparty/assimp/code/BlenderScene.h
deleted file mode 100644
index 58d6addd..00000000
--- a/3rdparty/assimp/code/BlenderScene.h
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderScene.h
- * @brief Intermediate representation of a BLEND scene.
- */
-#ifndef INCLUDED_AI_BLEND_SCENE_H
-#define INCLUDED_AI_BLEND_SCENE_H
-
-namespace Assimp {
- namespace Blender {
-
-// Minor parts of this file are extracts from blender data structures,
-// declared in the ./source/blender/makesdna directory.
-// Stuff that is not used by Assimp is commented.
-
-
-// NOTE
-// this file serves as input data to the `./scripts/genblenddna.py`
-// script. This script generates the actual binding code to read a
-// blender file with a possibly different DNA into our structures.
-// Only `struct` declarations are considered and the following
-// rules must be obeyed in order for the script to work properly:
-//
-// * C++ style comments only
-//
-// * Structures may include the primitive types char, int, short,
-// float, double. Signedness specifiers are not allowed on
-// integers. Enum types are allowed, but they must have been
-// defined in this header.
-//
-// * Structures may aggregate other structures, unless not defined
-// in this header.
-//
-// * Pointers to other structures or primitive types are allowed.
-// No references or double pointers or arrays of pointers.
-// A pointer to a T is written as boost::shared_ptr, while a
-// pointer to an array of elements is written as boost::
-// shared_array.
-//
-// * Arrays can have maximally two-dimensions. Any non-pointer
-// type can form them.
-//
-// * Multiple fields can be declare in a single line (i.e `int a,b;`)
-// provided they are neither pointers nor arrays.
-//
-// * One of WARN, FAIL can be appended to the declaration (
-// prior to the semiolon to specifiy the error handling policy if
-// this field is missing in the input DNA). If none of those
-// is specified the default policy is to subtitute a default
-// value for the field.
-//
-
-#define WARN // warn if field is missing, substitute default value
-#define FAIL // fail the import if the field does not exist
-
-struct Object;
-struct MTex;
-
-#define AI_BLEND_MESH_MAX_VERTS 2000000000L
-
-// -------------------------------------------------------------------------------
-struct ID : ElemBase {
-
- char name[24] WARN;
- short flag;
-};
-
-// -------------------------------------------------------------------------------
-struct ListBase : ElemBase {
-
- boost::shared_ptr<ElemBase> first;
- boost::shared_ptr<ElemBase> last;
-};
-
-
-// -------------------------------------------------------------------------------
-struct PackedFile : ElemBase {
- int size WARN;
- int seek WARN;
- boost::shared_ptr< FileOffset > data WARN;
-};
-
-// -------------------------------------------------------------------------------
-struct GroupObject : ElemBase {
-
- boost::shared_ptr<GroupObject> prev,next FAIL;
- boost::shared_ptr<Object> ob;
-};
-
-// -------------------------------------------------------------------------------
-struct Group : ElemBase {
- ID id FAIL;
- int layer;
-
- boost::shared_ptr<GroupObject> gobject;
-};
-
-// -------------------------------------------------------------------------------
-struct World : ElemBase {
- ID id FAIL;
-
-};
-
-// -------------------------------------------------------------------------------
-struct MVert : ElemBase {
- float co[3] FAIL;
- float no[3] FAIL;
- char flag;
- int mat_nr WARN;
- int bweight;
-};
-
-// -------------------------------------------------------------------------------
-struct MEdge : ElemBase {
- int v1, v2 FAIL;
- char crease, bweight;
- short flag;
-};
-
-// -------------------------------------------------------------------------------
-struct MCol : ElemBase {
- char r,g,b,a FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct MFace : ElemBase {
- int v1,v2,v3,v4 FAIL;
- int mat_nr FAIL;
- char flag;
-};
-
-// -------------------------------------------------------------------------------
-struct TFace : ElemBase {
- float uv[4][2] FAIL;
- int col[4] FAIL;
- char flag;
- short mode;
- short tile;
- short unwrap;
-};
-
-// -------------------------------------------------------------------------------
-struct MTFace : ElemBase {
-
- float uv[4][2] FAIL;
- char flag;
- short mode;
- short tile;
- short unwrap;
-
- // boost::shared_ptr<Image> tpage;
-};
-
-// -------------------------------------------------------------------------------
-struct MDeformWeight : ElemBase {
- int def_nr FAIL;
- float weight FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct MDeformVert : ElemBase {
-
- vector<MDeformWeight> dw WARN;
- int totweight;
-};
-
-// -------------------------------------------------------------------------------
-struct Material : ElemBase {
- ID id FAIL;
-
- float r,g,b WARN;
- float specr,specg,specb WARN;
- float ambir,ambig,ambib WARN;
- float mirr,mirg,mirb;
- float emit WARN;
- float alpha WARN;
- float ref;
- float translucency;
- float roughness;
- float darkness;
- float refrac;
-
- boost::shared_ptr<Group> group;
-
- short diff_shader WARN;
- short spec_shader WARN;
-
- boost::shared_ptr<MTex> mtex[18];
-};
-
-// -------------------------------------------------------------------------------
-struct Mesh : ElemBase {
- ID id FAIL;
-
- int totface FAIL;
- int totedge FAIL;
- int totvert FAIL;
-
- short subdiv;
- short subdivr;
- short subsurftype;
- short smoothresh;
-
- vector<MFace> mface FAIL;
- vector<MTFace> mtface;
- vector<TFace> tface;
- vector<MVert> mvert FAIL;
- vector<MEdge> medge WARN;
- vector<MDeformVert> dvert;
- vector<MCol> mcol;
-
- vector< boost::shared_ptr<Material> > mat FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct Library : ElemBase {
- ID id FAIL;
-
- char name[240] WARN;
- char filename[240] FAIL;
- boost::shared_ptr<Library> parent WARN;
-};
-
-// -------------------------------------------------------------------------------
-struct Camera : ElemBase {
- enum Type {
- Type_PERSP = 0
- ,Type_ORTHO = 1
- };
-
- ID id FAIL;
-
- // struct AnimData *adt;
-
- Type type,flag WARN;
- float angle WARN;
- //float passepartalpha, angle;
- //float clipsta, clipend;
- //float lens, ortho_scale, drawsize;
- //float shiftx, shifty;
-
- //float YF_dofdist, YF_aperture;
- //short YF_bkhtype, YF_bkhbias;
- //float YF_bkhrot;
-};
-
-
-// -------------------------------------------------------------------------------
-struct Lamp : ElemBase {
-
- enum FalloffType {
- FalloffType_Constant = 0x0
- ,FalloffType_InvLinear = 0x1
- ,FalloffType_InvSquare = 0x2
- //,FalloffType_Curve = 0x3
- //,FalloffType_Sliders = 0x4
- };
-
- enum Type {
- Type_Local = 0x0
- ,Type_Sun = 0x1
- ,Type_Spot = 0x2
- ,Type_Hemi = 0x3
- ,Type_Area = 0x4
- //,Type_YFPhoton = 0x5
- };
-
- ID id FAIL;
- //AnimData *adt;
-
- Type type FAIL;
- short flags;
-
- //int mode;
-
- short colormodel, totex;
- float r,g,b,k WARN;
- //float shdwr, shdwg, shdwb;
-
- float energy, dist, spotsize, spotblend;
- //float haint;
-
- float att1, att2;
- //struct CurveMapping *curfalloff;
- FalloffType falloff_type;
-
- //float clipsta, clipend, shadspotsize;
- //float bias, soft, compressthresh;
- //short bufsize, samp, buffers, filtertype;
- //char bufflag, buftype;
-
- //short ray_samp, ray_sampy, ray_sampz;
- //short ray_samp_type;
- //short area_shape;
- //float area_size, area_sizey, area_sizez;
- //float adapt_thresh;
- //short ray_samp_method;
-
- //short texact, shadhalostep;
-
- //short sun_effect_type;
- //short skyblendtype;
- //float horizon_brightness;
- //float spread;
- float sun_brightness;
- //float sun_size;
- //float backscattered_light;
- //float sun_intensity;
- //float atm_turbidity;
- //float atm_inscattering_factor;
- //float atm_extinction_factor;
- //float atm_distance_factor;
- //float skyblendfac;
- //float sky_exposure;
- //short sky_colorspace;
-
- // int YF_numphotons, YF_numsearch;
- // short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
- // float YF_causticblur, YF_ltradius;
-
- // float YF_glowint, YF_glowofs;
- // short YF_glowtype, YF_pad2;
-
- //struct Ipo *ipo;
- //struct MTex *mtex[18];
- // short pr_texture;
-
- //struct PreviewImage *preview;
-};
-
-// -------------------------------------------------------------------------------
-struct ModifierData : ElemBase {
- enum ModifierType {
- eModifierType_None = 0,
- eModifierType_Subsurf,
- eModifierType_Lattice,
- eModifierType_Curve,
- eModifierType_Build,
- eModifierType_Mirror,
- eModifierType_Decimate,
- eModifierType_Wave,
- eModifierType_Armature,
- eModifierType_Hook,
- eModifierType_Softbody,
- eModifierType_Boolean,
- eModifierType_Array,
- eModifierType_EdgeSplit,
- eModifierType_Displace,
- eModifierType_UVProject,
- eModifierType_Smooth,
- eModifierType_Cast,
- eModifierType_MeshDeform,
- eModifierType_ParticleSystem,
- eModifierType_ParticleInstance,
- eModifierType_Explode,
- eModifierType_Cloth,
- eModifierType_Collision,
- eModifierType_Bevel,
- eModifierType_Shrinkwrap,
- eModifierType_Fluidsim,
- eModifierType_Mask,
- eModifierType_SimpleDeform,
- eModifierType_Multires,
- eModifierType_Surface,
- eModifierType_Smoke,
- eModifierType_ShapeKey
- };
-
- boost::shared_ptr<ElemBase> next WARN;
- boost::shared_ptr<ElemBase> prev WARN;
-
- int type, mode;
- char name[32];
-};
-
-// -------------------------------------------------------------------------------
-struct SubsurfModifierData : ElemBase {
-
- enum Type {
-
- TYPE_CatmullClarke = 0x0,
- TYPE_Simple = 0x1
- };
-
- enum Flags {
- // some ommitted
- FLAGS_SubsurfUV =1<<3
- };
-
- ModifierData modifier FAIL;
- short subdivType WARN;
- short levels FAIL;
- short renderLevels ;
- short flags;
-};
-
-// -------------------------------------------------------------------------------
-struct MirrorModifierData : ElemBase {
-
- enum Flags {
- Flags_CLIPPING =1<<0,
- Flags_MIRROR_U =1<<1,
- Flags_MIRROR_V =1<<2,
- Flags_AXIS_X =1<<3,
- Flags_AXIS_Y =1<<4,
- Flags_AXIS_Z =1<<5,
- Flags_VGROUP =1<<6
- };
-
- ModifierData modifier FAIL;
-
- short axis, flag;
- float tolerance;
- boost::shared_ptr<Object> mirror_ob;
-};
-
-// -------------------------------------------------------------------------------
-struct Object : ElemBase {
- ID id FAIL;
-
- enum Type {
- Type_EMPTY = 0
- ,Type_MESH = 1
- ,Type_CURVE = 2
- ,Type_SURF = 3
- ,Type_FONT = 4
- ,Type_MBALL = 5
-
- ,Type_LAMP = 10
- ,Type_CAMERA = 11
-
- ,Type_WAVE = 21
- ,Type_LATTICE = 22
- };
-
- Type type FAIL;
- float obmat[4][4] WARN;
- float parentinv[4][4] WARN;
- char parsubstr[32] WARN;
-
- boost::shared_ptr<Object> parent WARN;
- boost::shared_ptr<Object> track WARN;
-
- boost::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
- boost::shared_ptr<Group> dup_group WARN;
- boost::shared_ptr<ElemBase> data FAIL;
-
- ListBase modifiers;
-};
-
-
-// -------------------------------------------------------------------------------
-struct Base : ElemBase {
- boost::shared_ptr<Base> prev WARN;
- boost::shared_ptr<Base> next WARN;
- boost::shared_ptr<Object> object WARN;
-};
-
-// -------------------------------------------------------------------------------
-struct Scene : ElemBase {
- ID id FAIL;
-
- boost::shared_ptr<Object> camera WARN;
- boost::shared_ptr<World> world WARN;
- boost::shared_ptr<Base> basact WARN;
-
- ListBase base;
-};
-
-
-// -------------------------------------------------------------------------------
-struct Image : ElemBase {
- ID id FAIL;
-
- char name[240] WARN;
-
- //struct anim *anim;
-
- short ok, flag;
- short source, type, pad, pad1;
- int lastframe;
-
- short tpageflag, totbind;
- short xrep, yrep;
- short twsta, twend;
- //unsigned int bindcode;
- //unsigned int *repbind;
-
- boost::shared_ptr<PackedFile> packedfile;
- //struct PreviewImage * preview;
-
- float lastupdate;
- int lastused;
- short animspeed;
-
- short gen_x, gen_y, gen_type;
-};
-
-// -------------------------------------------------------------------------------
-struct Tex : ElemBase {
-
- // actually, the only texture type we support is Type_IMAGE
- enum Type {
- Type_CLOUDS = 1
- ,Type_WOOD = 2
- ,Type_MARBLE = 3
- ,Type_MAGIC = 4
- ,Type_BLEND = 5
- ,Type_STUCCI = 6
- ,Type_NOISE = 7
- ,Type_IMAGE = 8
- ,Type_PLUGIN = 9
- ,Type_ENVMAP = 10
- ,Type_MUSGRAVE = 11
- ,Type_VORONOI = 12
- ,Type_DISTNOISE = 13
- ,Type_POINTDENSITY = 14
- ,Type_VOXELDATA = 15
- };
-
- ID id FAIL;
- // AnimData *adt;
-
- //float noisesize, turbul;
- //float bright, contrast, rfac, gfac, bfac;
- //float filtersize;
-
- //float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
- //float dist_amount, ns_outscale;
-
- //float vn_w1;
- //float vn_w2;
- //float vn_w3;
- //float vn_w4;
- //float vn_mexp;
- //short vn_distm, vn_coltype;
-
- //short noisedepth, noisetype;
- //short noisebasis, noisebasis2;
-
- //short imaflag, flag;
- Type type FAIL;
- //short stype;
-
- //float cropxmin, cropymin, cropxmax, cropymax;
- //int texfilter;
- //int afmax;
- //short xrepeat, yrepeat;
- //short extend;
-
- //short fie_ima;
- //int len;
- //int frames, offset, sfra;
-
- //float checkerdist, nabla;
- //float norfac;
-
- //ImageUser iuser;
-
- //bNodeTree *nodetree;
- //Ipo *ipo;
- boost::shared_ptr<Image> ima WARN;
- //PluginTex *plugin;
- //ColorBand *coba;
- //EnvMap *env;
- //PreviewImage * preview;
- //PointDensity *pd;
- //VoxelData *vd;
-
- //char use_nodes;
-};
-
-// -------------------------------------------------------------------------------
-struct MTex : ElemBase {
-
- enum Projection {
- Proj_N = 0
- ,Proj_X = 1
- ,Proj_Y = 2
- ,Proj_Z = 3
- };
-
- enum Flag {
- Flag_RGBTOINT = 0x1
- ,Flag_STENCIL = 0x2
- ,Flag_NEGATIVE = 0x4
- ,Flag_ALPHAMIX = 0x8
- ,Flag_VIEWSPACE = 0x10
- };
-
- enum BlendType {
- BlendType_BLEND = 0
- ,BlendType_MUL = 1
- ,BlendType_ADD = 2
- ,BlendType_SUB = 3
- ,BlendType_DIV = 4
- ,BlendType_DARK = 5
- ,BlendType_DIFF = 6
- ,BlendType_LIGHT = 7
- ,BlendType_SCREEN = 8
- ,BlendType_OVERLAY = 9
- ,BlendType_BLEND_HUE = 10
- ,BlendType_BLEND_SAT = 11
- ,BlendType_BLEND_VAL = 12
- ,BlendType_BLEND_COLOR = 13
- };
-
- // short texco, mapto, maptoneg;
-
- BlendType blendtype;
- boost::shared_ptr<Object> object;
- boost::shared_ptr<Tex> tex;
- char uvname[32];
-
- Projection projx,projy,projz;
- char mapping;
- float ofs[3], size[3], rot;
-
- int texflag;
- short colormodel, pmapto, pmaptoneg;
- //short normapspace, which_output;
- //char brush_map_mode;
- float r,g,b,k WARN;
- //float def_var, rt;
-
- //float colfac, varfac;
-
- //float norfac, dispfac, warpfac;
- float colspecfac, mirrfac, alphafac;
- float difffac, specfac, emitfac, hardfac;
- //float raymirrfac, translfac, ambfac;
- //float colemitfac, colreflfac, coltransfac;
- //float densfac, scatterfac, reflfac;
-
- //float timefac, lengthfac, clumpfac;
- //float kinkfac, roughfac, padensfac;
- //float lifefac, sizefac, ivelfac, pvelfac;
- //float shadowfac;
- //float zenupfac, zendownfac, blendfac;
-};
-
-
- }
-}
-#endif
diff --git a/3rdparty/assimp/code/BlenderSceneGen.h b/3rdparty/assimp/code/BlenderSceneGen.h
deleted file mode 100644
index 0a7096e5..00000000
--- a/3rdparty/assimp/code/BlenderSceneGen.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file BlenderSceneGen.h
- * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
- */
-#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
-#define INCLUDED_AI_BLEND_SCENEGEN_H
-
-namespace Assimp {
- namespace Blender {
-
-
-template <> void Structure :: Convert<Object> (
- Object& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Group> (
- Group& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MTex> (
- MTex& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<TFace> (
- TFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<SubsurfModifierData> (
- SubsurfModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MFace> (
- MFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Lamp> (
- Lamp& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MDeformWeight> (
- MDeformWeight& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<PackedFile> (
- PackedFile& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Base> (
- Base& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MTFace> (
- MTFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Material> (
- Material& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Mesh> (
- Mesh& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MDeformVert> (
- MDeformVert& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<World> (
- World& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MVert> (
- MVert& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MEdge> (
- MEdge& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<GroupObject> (
- GroupObject& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ListBase> (
- ListBase& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ModifierData> (
- ModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ID> (
- ID& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MCol> (
- MCol& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Image> (
- Image& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Scene> (
- Scene& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Library> (
- Library& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Tex> (
- Tex& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Camera> (
- Camera& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MirrorModifierData> (
- MirrorModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-
- }
-}
-
-#endif
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/LICENSE_1_0.txt b/3rdparty/assimp/code/BoostWorkaround/boost/LICENSE_1_0.txt
deleted file mode 100644
index 7925d62e..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/LICENSE_1_0.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/foreach.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/foreach.hpp
deleted file mode 100644
index dfb05bdf..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/foreach.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-
-#ifndef BOOST_FOREACH
-
-///////////////////////////////////////////////////////////////////////////////
-// A stripped down version of FOREACH for
-// illustration purposes. NOT FOR GENERAL USE.
-// For a complete implementation, see BOOST_FOREACH at
-// http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler
-//
-// Copyright 2004 Eric Niebler.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// Adapted to Assimp November 29th, 2008 (Alexander Gessler).
-// Added code to handle both const and non-const iterators, simplified some
-// parts.
-///////////////////////////////////////////////////////////////////////////////
-
-namespace boost {
-namespace foreach_detail {
-
-///////////////////////////////////////////////////////////////////////////////
-// auto_any
-
-struct auto_any_base
-{
- operator bool() const { return false; }
-};
-
-template<typename T>
-struct auto_any : auto_any_base
-{
- auto_any(T const& t) : item(t) {}
- mutable T item;
-};
-
-template<typename T>
-T& auto_any_cast(auto_any_base const& any)
-{
- return static_cast<auto_any<T> const&>(any).item;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// FOREACH helper function
-
-template<typename T>
-auto_any<typename T::const_iterator> begin(T const& t)
-{
- return t.begin();
-}
-
-template<typename T>
-auto_any<typename T::const_iterator> end(T const& t)
-{
- return t.end();
-}
-
-// iterator
-template<typename T>
-bool done(auto_any_base const& cur, auto_any_base const& end, T&)
-{
- typedef typename T::iterator iter_type;
- return auto_any_cast<iter_type>(cur) == auto_any_cast<iter_type>(end);
-}
-
-template<typename T>
-void next(auto_any_base const& cur, T&)
-{
- ++auto_any_cast<typename T::iterator>(cur);
-}
-
-template<typename T>
-typename T::reference deref(auto_any_base const& cur, T&)
-{
- return *auto_any_cast<typename T::iterator>(cur);
-}
-
-} // end foreach_detail
-
-///////////////////////////////////////////////////////////////////////////////
-// FOREACH
-
-#define BOOST_FOREACH(item, container) \
- if (boost::foreach_detail::auto_any_base const& b = boost::foreach_detail::begin(container)) {} else \
- if (boost::foreach_detail::auto_any_base const& e = boost::foreach_detail::end(container)) {} else \
- for (;!boost::foreach_detail::done(b,e,container); boost::foreach_detail::next(b,container)) \
- if (bool ugly_and_unique_break = false) {} else \
- for (item = boost::foreach_detail::deref(b,container); !ugly_and_unique_break; ugly_and_unique_break = true)
-
-} // end boost
-
-#endif
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/format.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/format.hpp
deleted file mode 100644
index b7d956b2..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/format.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-/* DEPRECATED! - use code/TinyFormatter.h instead.
- *
- *
- * */
-
-#ifndef AI_BOOST_FORMAT_DUMMY_INCLUDED
-#define AI_BOOST_FORMAT_DUMMY_INCLUDED
-
-#if (!defined BOOST_FORMAT_HPP) || (defined ASSIMP_FORCE_NOBOOST)
-
-#include <string>
-#include <vector>
-
-namespace boost
-{
-
-
- class format
- {
- public:
- format (const std::string& _d)
- : d(_d)
- {
- }
-
- template <typename T>
- format& operator % (T in)
- {
- // XXX add replacement for boost::lexical_cast?
-
- std::stringstream ss;
- ss << in; // note: ss cannot be an rvalue, or the global operator << (const char*) is not called for T == const char*.
- chunks.push_back( ss.str());
- return *this;
- }
-
-
- operator std::string () const {
- std::string res; // pray for NRVO to kick in
-
- size_t start = 0, last = 0;
-
- std::vector<std::string>::const_iterator chunkin = chunks.begin();
-
- for ( start = d.find('%');start != std::string::npos; start = d.find('%',last)) {
- res += d.substr(last,start-last);
- last = start+2;
- if (d[start+1] == '%') {
- res += "%";
- continue;
- }
-
- if (chunkin == chunks.end()) {
- break;
- }
-
- res += *chunkin++;
- }
- res += d.substr(last);
- return res;
- }
-
- private:
- std::string d;
- std::vector<std::string> chunks;
- };
-
- inline std::string str(const std::string& s) {
- return s;
- }
-}
-
-
-#else
-# error "format.h was already included"
-#endif //
-#endif // !! AI_BOOST_FORMAT_DUMMY_INCLUDED
-
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp
deleted file mode 100644
index 6c3f7819..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/// A quick replacement for boost::lexical_cast for all the Boost haters out there
-
-#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
-#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
-
-namespace boost
-{
-
- /// A quick replacement for boost::lexical_cast - should work for all types a stringstream can handle
- template <typename TargetType, typename SourceType>
- TargetType lexical_cast( const SourceType& source)
- {
- std::stringstream stream;
- TargetType result;
-
- stream << source;
- stream >> result;
- return result;
- }
-
-} // namespace boost
-
-#endif // __AI_BOOST_WORKAROUND_LEXICAL_CAST
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/math/common_factor_rt.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/math/common_factor_rt.hpp
deleted file mode 100644
index 8b07f69b..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/math/common_factor_rt.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
-#define BOOST_MATH_COMMON_FACTOR_RT_HPP
-
-
-namespace boost {
-namespace math {
-
-// TODO: use binary GCD for unsigned integers ....
-template < typename IntegerType >
-IntegerType gcd( IntegerType a, IntegerType b )
-{
- const IntegerType zero = (IntegerType)0;
- while ( true )
- {
- if ( a == zero )
- return b;
- b %= a;
-
- if ( b == zero )
- return a;
- a %= b;
- }
-}
-
-template < typename IntegerType >
-IntegerType lcm( IntegerType a, IntegerType b )
-{
- const IntegerType t = gcd (a,b);
- if (!t)return t;
- return a / t * b;
-}
-
-}}
-
-#endif
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/pointer_cast.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/pointer_cast.hpp
deleted file mode 100644
index ce188c13..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/pointer_cast.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_POINTER_CAST_HPP
-#define BOOST_POINTER_CAST_HPP
-
-namespace boost {
-
-//static_pointer_cast overload for raw pointers
-template<class T, class U>
-inline T* static_pointer_cast(U *ptr)
-{
- return static_cast<T*>(ptr);
-}
-
-//dynamic_pointer_cast overload for raw pointers
-template<class T, class U>
-inline T* dynamic_pointer_cast(U *ptr)
-{
- return dynamic_cast<T*>(ptr);
-}
-
-//const_pointer_cast overload for raw pointers
-template<class T, class U>
-inline T* const_pointer_cast(U *ptr)
-{
- return const_cast<T*>(ptr);
-}
-
-//reinterpret_pointer_cast overload for raw pointers
-template<class T, class U>
-inline T* reinterpret_pointer_cast(U *ptr)
-{
- return reinterpret_cast<T*>(ptr);
-}
-
-} // namespace boost
-
-#endif //BOOST_POINTER_CAST_HPP
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/scoped_array.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/scoped_array.hpp
deleted file mode 100644
index cd739819..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/scoped_array.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-
-#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED
-#define __AI_BOOST_SCOPED_ARRAY_INCLUDED
-
-#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
-
-namespace boost {
-
-// small replacement for boost::scoped_array
-template <class T>
-class scoped_array
-{
-public:
-
- // provide a default construtctor
- scoped_array()
- : ptr(0)
- {
- }
-
- // construction from an existing heap object of type T
- scoped_array(T* _ptr)
- : ptr(_ptr)
- {
- }
-
- // automatic destruction of the wrapped object at the
- // end of our lifetime
- ~scoped_array()
- {
- delete[] ptr;
- }
-
- inline T* get()
- {
- return ptr;
- }
-
- inline T* operator-> ()
- {
- return ptr;
- }
-
- inline void reset (T* t = 0)
- {
- delete[] ptr;
- ptr = t;
- }
-
- T & operator[](std::ptrdiff_t i) const
- {
- return ptr[i];
- }
-
- void swap(scoped_array & b)
- {
- std::swap(ptr, b.ptr);
- }
-
-private:
-
- // encapsulated object pointer
- T* ptr;
-
-};
-
-template<class T>
-inline void swap(scoped_array<T> & a, scoped_array<T> & b)
-{
- a.swap(b);
-}
-
-} // end of namespace boost
-
-#else
-# error "scoped_array.h was already included"
-#endif
-#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED
-
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/scoped_ptr.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/scoped_ptr.hpp
deleted file mode 100644
index 84021a82..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/scoped_ptr.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-
-#ifndef __AI_BOOST_SCOPED_PTR_INCLUDED
-#define __AI_BOOST_SCOPED_PTR_INCLUDED
-
-#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
-
-namespace boost {
-
-// small replacement for boost::scoped_ptr
-template <class T>
-class scoped_ptr
-{
-public:
-
- // provide a default construtctor
- scoped_ptr()
- : ptr(0)
- {
- }
-
- // construction from an existing heap object of type T
- scoped_ptr(T* _ptr)
- : ptr(_ptr)
- {
- }
-
- // automatic destruction of the wrapped object at the
- // end of our lifetime
- ~scoped_ptr()
- {
- delete ptr;
- }
-
- inline T* get() const
- {
- return ptr;
- }
-
- inline operator T*()
- {
- return ptr;
- }
-
- inline T* operator-> ()
- {
- return ptr;
- }
-
- inline void reset (T* t = 0)
- {
- delete ptr;
- ptr = t;
- }
-
- void swap(scoped_ptr & b)
- {
- std::swap(ptr, b.ptr);
- }
-
-private:
-
- // encapsulated object pointer
- T* ptr;
-
-};
-
-template<class T>
-inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
-{
- a.swap(b);
-}
-
-} // end of namespace boost
-
-#else
-# error "scoped_ptr.h was already included"
-#endif
-#endif // __AI_BOOST_SCOPED_PTR_INCLUDED
-
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/shared_array.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/shared_array.hpp
deleted file mode 100644
index 7f604ae0..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/shared_array.hpp
+++ /dev/null
@@ -1,228 +0,0 @@
-
-#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY
-#define INCLUDED_AI_BOOST_SHARED_ARRAY
-
-#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
-
-// ------------------------------
-// Internal stub
-namespace boost {
- namespace array_detail {
- class controller {
- public:
-
- controller()
- : cnt(1)
- {}
-
- public:
-
- template <typename T>
- controller* decref(T* pt) {
- if (--cnt <= 0) {
- delete this;
- delete[] pt;
- }
- return NULL;
- }
-
- controller* incref() {
- ++cnt;
- return this;
- }
-
- long get() const {
- return cnt;
- }
-
- private:
- long cnt;
- };
-
- struct empty {};
-
- template <typename DEST, typename SRC>
- struct is_convertible_stub {
-
- struct yes {char s[1];};
- struct no {char s[2];};
-
- static yes foo(DEST*);
- static no foo(...);
-
- enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
- };
-
- template <bool> struct enable_if {};
- template <> struct enable_if<true> {
- typedef empty result;
- };
-
- template <typename DEST, typename SRC>
- struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
- };
- }
-
-// ------------------------------
-// Small replacement for boost::shared_array, not threadsafe because no
-// atomic reference counter is in use.
-// ------------------------------
-template <class T>
-class shared_array
-{
- template <typename TT> friend class shared_array;
-
- template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
- template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
- template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b);
-
-public:
-
- typedef T element_type;
-
-public:
-
- // provide a default constructor
- shared_array()
- : ptr()
- , ctr(NULL)
- {
- }
-
- // construction from an existing object of type T
- explicit shared_array(T* ptr)
- : ptr(ptr)
- , ctr(ptr ? new array_detail::controller() : NULL)
- {
- }
-
- shared_array(const shared_array& r)
- : ptr(r.ptr)
- , ctr(r.ctr ? r.ctr->incref() : NULL)
- {
- }
-
- template <typename Y>
- shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
- : ptr(r.ptr)
- , ctr(r.ctr ? r.ctr->incref() : NULL)
- {
- }
-
- // automatic destruction of the wrapped object when all
- // references are freed.
- ~shared_array() {
- if (ctr) {
- ctr = ctr->decref(ptr);
- }
- }
-
- shared_array& operator=(const shared_array& r) {
- if (this == &r) {
- return *this;
- }
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = r.ptr;
- ctr = ptr?r.ctr->incref():NULL;
- return *this;
- }
-
- template <typename Y>
- shared_array& operator=(const shared_array<Y>& r) {
- if (this == &r) {
- return *this;
- }
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = r.ptr;
- ctr = ptr?r.ctr->incref():NULL;
- return *this;
- }
-
- // pointer access
- inline operator T*() {
- return ptr;
- }
-
- inline T* operator-> () const {
- return ptr;
- }
-
- // standard semantics
- inline T* get() {
- return ptr;
- }
-
- T& operator[] (std::ptrdiff_t index) const {
- return ptr[index];
- }
-
- inline const T* get() const {
- return ptr;
- }
-
- inline operator bool () const {
- return ptr != NULL;
- }
-
- inline bool unique() const {
- return use_count() == 1;
- }
-
- inline long use_count() const {
- return ctr->get();
- }
-
- inline void reset (T* t = 0) {
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = t;
- ctr = ptr?new array_detail::controller():NULL;
- }
-
- void swap(shared_array & b) {
- std::swap(ptr, b.ptr);
- std::swap(ctr, b.ctr);
- }
-
-
-private:
-
- // encapsulated object pointer
- T* ptr;
-
- // control block
- array_detail::controller* ctr;
-};
-
-template<class T>
-inline void swap(shared_array<T> & a, shared_array<T> & b)
-{
- a.swap(b);
-}
-
-template<class T>
-bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
- return a.ptr == b.ptr;
-}
-template<class T>
-bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
- return a.ptr != b.ptr;
-}
-
-template<class T>
-bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
- return a.ptr < b.ptr;
-}
-
-
-} // end of namespace boost
-
-#else
-# error "shared_array.h was already included"
-#endif
-#endif // INCLUDED_AI_BOOST_SHARED_ARRAY
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/shared_ptr.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/shared_ptr.hpp
deleted file mode 100644
index f0dd4491..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/shared_ptr.hpp
+++ /dev/null
@@ -1,257 +0,0 @@
-
-#ifndef INCLUDED_AI_BOOST_SHARED_PTR
-#define INCLUDED_AI_BOOST_SHARED_PTR
-
-#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
-
-// ------------------------------
-// Internal stub
-namespace boost {
- namespace detail {
- class controller {
- public:
-
- controller()
- : cnt(1)
- {}
-
- public:
-
- template <typename T>
- controller* decref(T* pt) {
- if (--cnt <= 0) {
- delete this;
- delete pt;
- }
- return NULL;
- }
-
- controller* incref() {
- ++cnt;
- return this;
- }
-
- long get() const {
- return cnt;
- }
-
- private:
- long cnt;
- };
-
- struct empty {};
-
- template <typename DEST, typename SRC>
- struct is_convertible_stub {
-
- struct yes {char s[1];};
- struct no {char s[2];};
-
- static yes foo(DEST*);
- static no foo(...);
-
- enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
- };
-
- template <bool> struct enable_if {};
- template <> struct enable_if<true> {
- typedef empty result;
- };
-
- template <typename DEST, typename SRC>
- struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
- };
- }
-
-// ------------------------------
-// Small replacement for boost::shared_ptr, not threadsafe because no
-// atomic reference counter is in use.
-// ------------------------------
-template <class T>
-class shared_ptr
-{
- template <typename TT> friend class shared_ptr;
-
- template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
- template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
- template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
-
- template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
- template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
- template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
-
-public:
-
- typedef T element_type;
-
-public:
-
- // provide a default constructor
- shared_ptr()
- : ptr()
- , ctr(NULL)
- {
- }
-
- // construction from an existing object of type T
- explicit shared_ptr(T* ptr)
- : ptr(ptr)
- , ctr(ptr ? new detail::controller() : NULL)
- {
- }
-
- shared_ptr(const shared_ptr& r)
- : ptr(r.ptr)
- , ctr(r.ctr ? r.ctr->incref() : NULL)
- {
- }
-
- template <typename Y>
- shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
- : ptr(r.ptr)
- , ctr(r.ctr ? r.ctr->incref() : NULL)
- {
- }
-
- // automatic destruction of the wrapped object when all
- // references are freed.
- ~shared_ptr() {
- if (ctr) {
- ctr = ctr->decref(ptr);
- }
- }
-
- shared_ptr& operator=(const shared_ptr& r) {
- if (this == &r) {
- return *this;
- }
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = r.ptr;
- ctr = ptr?r.ctr->incref():NULL;
- return *this;
- }
-
- template <typename Y>
- shared_ptr& operator=(const shared_ptr<Y>& r) {
- if (this == &r) {
- return *this;
- }
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = r.ptr;
- ctr = ptr?r.ctr->incref():NULL;
- return *this;
- }
-
- // pointer access
- inline operator T*() {
- return ptr;
- }
-
- inline T* operator-> () const {
- return ptr;
- }
-
- // standard semantics
- inline T* get() {
- return ptr;
- }
-
- inline const T* get() const {
- return ptr;
- }
-
- inline operator bool () const {
- return ptr != NULL;
- }
-
- inline bool unique() const {
- return use_count() == 1;
- }
-
- inline long use_count() const {
- return ctr->get();
- }
-
- inline void reset (T* t = 0) {
- if (ctr) {
- ctr->decref(ptr);
- }
- ptr = t;
- ctr = ptr?new detail::controller():NULL;
- }
-
- void swap(shared_ptr & b) {
- std::swap(ptr, b.ptr);
- std::swap(ctr, b.ctr);
- }
-
-private:
-
-
- // for use by the various xxx_pointer_cast helper templates
- explicit shared_ptr(T* ptr, detail::controller* ctr)
- : ptr(ptr)
- , ctr(ctr->incref())
- {
- }
-
-private:
-
- // encapsulated object pointer
- T* ptr;
-
- // control block
- detail::controller* ctr;
-};
-
-template<class T>
-inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
-{
- a.swap(b);
-}
-
-template<class T>
-bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
- return a.ptr == b.ptr;
-}
-template<class T>
-bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
- return a.ptr != b.ptr;
-}
-
-template<class T>
-bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
- return a.ptr < b.ptr;
-}
-
-
-template<class T, class U>
-inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
-{
- return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
-}
-
-template<class T, class U>
-inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
-{
- return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
-}
-
-template<class T, class U>
-inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
-{
- return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
-}
-
-
-
-} // end of namespace boost
-
-#else
-# error "shared_ptr.h was already included"
-#endif
-#endif // INCLUDED_AI_BOOST_SCOPED_PTR
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/static_assert.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/static_assert.hpp
deleted file mode 100644
index 4ee728ba..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/static_assert.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef AI_BOOST_STATIC_ASSERT_INCLUDED
-#define AI_BOOST_STATIC_ASSERT_INCLUDED
-
-#ifndef BOOST_STATIC_ASSERT
-
-namespace boost {
- namespace detail {
-
- template <bool b> class static_assertion_failure;
- template <> class static_assertion_failure<true> {};
- }
-}
-
-
-#define BOOST_STATIC_ASSERT(eval) \
-{boost::detail::static_assertion_failure<(eval)> assert_dummy; (void)assert_dummy;}
-
-#endif
-#endif // !! AI_BOOST_STATIC_ASSERT_INCLUDED
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/timer.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/timer.hpp
deleted file mode 100644
index edf2df88..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/timer.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// boost timer.hpp header file ---------------------------------------------//
-
-// Copyright Beman Dawes 1994-99. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org/libs/timer for documentation.
-
-// Revision History
-// 01 Apr 01 Modified to use new <boost/limits.hpp> header. (JMaddock)
-// 12 Jan 01 Change to inline implementation to allow use without library
-// builds. See docs for more rationale. (Beman Dawes)
-// 25 Sep 99 elapsed_max() and elapsed_min() added (John Maddock)
-// 16 Jul 99 Second beta
-// 6 Jul 99 Initial boost version
-
-#ifndef BOOST_TIMER_HPP
-#define BOOST_TIMER_HPP
-
-//#include <boost/config.hpp>
-#include <ctime>
-#include <time.h>
-//#include <boost/limits.hpp>
-
-# ifdef BOOST_NO_STDC_NAMESPACE
- namespace std { using ::clock_t; using ::clock; }
-# endif
-
-//symbian workarounds for CLOCKS_PER_SEC
-#ifndef CLOCKS_PER_SEC
-#ifndef __CLK_TCK
-# warning CLOCKS_PER_SEC is undefined... defaulting to 100 (as per RVCT time.h)
-# define CLOCKS_PER_SEC 100
-#else
-# define CLOCKS_PER_SEC __CLK_TCK
-#endif
-#endif
-
-namespace boost {
-
-// timer -------------------------------------------------------------------//
-
-// A timer object measures elapsed time.
-
-// It is recommended that implementations measure wall clock rather than CPU
-// time since the intended use is performance measurement on systems where
-// total elapsed time is more important than just process or CPU time.
-
-// Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
-// due to implementation limitations. The accuracy of timings depends on the
-// accuracy of timing information provided by the underlying platform, and
-// this varies a great deal from platform to platform.
-
-class timer
-{
- public:
- timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
-// timer( const timer& src ); // post: elapsed()==src.elapsed()
-// ~timer(){}
-// timer& operator=( const timer& src ); // post: elapsed()==src.elapsed()
- void restart() { _start_time = std::clock(); } // post: elapsed()==0
- double elapsed() const // return elapsed time in seconds
- { return double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
-
- double elapsed_max() const // return estimated maximum value for elapsed()
- // Portability warning: elapsed_max() may return too high a value on systems
- // where std::clock_t overflows or resets at surprising values.
- {
- return (double((std::numeric_limits<std::clock_t>::max)())
- - double(_start_time)) / double(CLOCKS_PER_SEC);
- }
-
- double elapsed_min() const // return minimum value for elapsed()
- { return double(1)/double(CLOCKS_PER_SEC); }
-
- private:
- std::clock_t _start_time;
-}; // timer
-
-} // namespace boost
-
-#endif // BOOST_TIMER_HPP
diff --git a/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp b/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp
deleted file mode 100644
index afd37bd7..00000000
--- a/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp
+++ /dev/null
@@ -1,285 +0,0 @@
-// A very small replacement for boost::tuple
-// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net]
-
-#ifndef BOOST_TUPLE_INCLUDED
-#define BOOST_TUPLE_INCLUDED
-
-namespace boost {
- namespace detail {
-
- // Represents an empty tuple slot (up to 5 supported)
- struct nulltype {};
-
- // For readable error messages
- struct tuple_component_idx_out_of_bounds;
-
- // To share some code for the const/nonconst versions of the getters
- template <bool b, typename T>
- struct ConstIf {
- typedef T t;
- };
-
- template <typename T>
- struct ConstIf<true,T> {
- typedef const T t;
- };
-
- // Predeclare some stuff
- template <typename, unsigned, typename, bool, unsigned> struct value_getter;
-
- // Helper to obtain the type of a tuple element
- template <typename T, unsigned NIDX, typename TNEXT, unsigned N /*= 0*/>
- struct type_getter {
- typedef type_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,N> next_elem_getter;
- typedef typename next_elem_getter::type type;
- };
-
- template <typename T, unsigned NIDX, typename TNEXT >
- struct type_getter <T,NIDX,TNEXT,NIDX> {
- typedef T type;
- };
-
- // Base class for all explicit specializations of list_elem
- template <typename T, unsigned NIDX, typename TNEXT >
- struct list_elem_base {
-
- // Store template parameters
- typedef TNEXT next_type;
- typedef T type;
-
- static const unsigned nidx = NIDX;
- };
-
- // Represents an element in the tuple component list
- template <typename T, unsigned NIDX, typename TNEXT >
- struct list_elem : list_elem_base<T,NIDX,TNEXT>{
-
- // Real members
- T me;
- TNEXT next;
-
- // Get the value of a specific tuple element
- template <unsigned N>
- typename type_getter<T,NIDX,TNEXT,N>::type& get () {
- value_getter <T,NIDX,TNEXT,false,N> s;
- return s(*this);
- }
-
- // Get the value of a specific tuple element
- template <unsigned N>
- const typename type_getter<T,NIDX,TNEXT,N>::type& get () const {
- value_getter <T,NIDX,TNEXT,true,N> s;
- return s(*this);
- }
-
- // Explicit cast
- template <typename T2, typename TNEXT2 >
- operator list_elem<T2,NIDX,TNEXT2> () const {
- list_elem<T2,NIDX,TNEXT2> ret;
- ret.me = (T2)me;
- ret.next = next;
- return ret;
- }
-
- // Recursively compare two elements (last element returns always true)
- bool operator == (const list_elem& s) const {
- return (me == s.me && next == s.next);
- }
- };
-
- // Represents a non-used tuple element - the very last element processed
- template <typename TNEXT, unsigned NIDX >
- struct list_elem<nulltype,NIDX,TNEXT> : list_elem_base<nulltype,NIDX,TNEXT> {
- template <unsigned N, bool IS_CONST = true> struct value_getter {
- /* just dummy members to produce readable error messages */
- tuple_component_idx_out_of_bounds operator () (typename ConstIf<IS_CONST,list_elem>::t& me);
- };
- template <unsigned N> struct type_getter {
- /* just dummy members to produce readable error messages */
- typedef tuple_component_idx_out_of_bounds type;
- };
-
- // dummy
- list_elem& operator = (const list_elem& other) {
- return *this;
- }
-
- // dummy
- bool operator == (const list_elem& other) {
- return true;
- }
- };
-
- // Represents the absolute end of the list
- typedef list_elem<nulltype,0,int> list_end;
-
- // Helper obtain to query the value of a tuple element
- // NOTE: This can't be a nested class as the compiler won't accept a full or
- // partial specialization of a nested class of a non-specialized template
- template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST, unsigned N>
- struct value_getter {
-
- // calling list_elem
- typedef list_elem<T,NIDX,TNEXT> outer_elem;
-
- // typedef for the getter for next element
- typedef value_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,
- IS_CONST, N> next_value_getter;
-
- typename ConstIf<IS_CONST,typename type_getter<T,NIDX,TNEXT,N>::type>::t&
- operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
-
- next_value_getter s;
- return s(me.next);
- }
- };
-
- template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST>
- struct value_getter <T,NIDX,TNEXT,IS_CONST,NIDX> {
- typedef list_elem<T,NIDX,TNEXT> outer_elem;
-
- typename ConstIf<IS_CONST,T>::t& operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
- return me.me;
- }
- };
- };
-
- // A very minimal implementation for up to 5 elements
- template <typename T0 = detail::nulltype,
- typename T1 = detail::nulltype,
- typename T2 = detail::nulltype,
- typename T3 = detail::nulltype,
- typename T4 = detail::nulltype>
- class tuple {
-
- template <typename T0b,
- typename T1b,
- typename T2b,
- typename T3b,
- typename T4b >
- friend class tuple;
-
- private:
-
- typedef detail::list_elem<T0,0,
- detail::list_elem<T1,1,
- detail::list_elem<T2,2,
- detail::list_elem<T3,3,
- detail::list_elem<T4,4,
- detail::list_end > > > > > very_long;
-
- very_long m;
-
- public:
-
- // Get a specific tuple element
- template <unsigned N>
- typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () {
- return m.get<N>();
- }
-
- // ... and the const version
- template <unsigned N>
- typename const detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const {
- return m.get<N>();
- }
-
-
- // comparison operators
- bool operator== (const tuple& other) const {
- return m == other.m;
- }
-
- // ... and the other way round
- bool operator!= (const tuple& other) const {
- return !(m == other.m);
- }
-
- // cast to another tuple - all single elements must be convertible
- template < typename T0, typename T1,typename T2,
- typename T3, typename T4>
-
- operator tuple <T0,T1,T2,T3,T4> () const {
- tuple <T0,T1,T2,T3,T4> s;
- s.m = (tuple <T0,T1,T2,T3,T4>::very_long)m;
- return s;
- }
- };
-
- // Another way to access an element ...
- template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
- inline typename tuple<T0,T1,T2,T3,T4>::very_long::type_getter<N>::type& get (
- tuple<T0,T1,T2,T3,T4>& m) {
- return m.get<N>();
- }
-
- // ... and the const version
- template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
- inline const typename tuple<T0,T1,T2,T3,T4>::very_long::type_getter<N>::type& get (
- const tuple<T0,T1,T2,T3,T4>& m) {
- return m.get<N>();
- }
-
- // Constructs a tuple with 5 elements
- template <typename T0,typename T1,typename T2,typename T3,typename T4>
- inline tuple <T0,T1,T2,T3,T4> make_tuple (const T0& t0,
- const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
-
- tuple <T0,T1,T2,T3,T4> t;
- t.get<0>() = t0;
- t.get<1>() = t1;
- t.get<2>() = t2;
- t.get<3>() = t3;
- t.get<4>() = t4;
- return t;
- }
-
- // Constructs a tuple with 4 elements
- template <typename T0,typename T1,typename T2,typename T3>
- inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
- const T1& t1,const T2& t2,const T3& t3) {
- tuple <T0,T1,T2,T3> t;
- t.get<0>() = t0;
- t.get<1>() = t1;
- t.get<2>() = t2;
- t.get<3>() = t3;
- return t;
- }
-
- // Constructs a tuple with 3 elements
- template <typename T0,typename T1,typename T2>
- inline tuple <T0,T1,T2> make_tuple (const T0& t0,
- const T1& t1,const T2& t2) {
- tuple <T0,T1,T2> t;
- t.get<0>() = t0;
- t.get<1>() = t1;
- t.get<2>() = t2;
- return t;
- }
-
- // Constructs a tuple with 2 elements (fucking idiot, use std::pair instead!)
- template <typename T0,typename T1>
- inline tuple <T0,T1> make_tuple (const T0& t0,
- const T1& t1) {
- tuple <T0,T1> t;
- t.get<0>() = t0;
- t.get<1>() = t1;
- return t;
- }
-
- // Constructs a tuple with 1 elements (no comment ...)
- template <typename T0>
- inline tuple <T0> make_tuple (const T0& t0) {
- tuple <T0> t;
- t.get<0>() = t0;
- return t;
- }
-
- // Constructs a tuple with 0 elements (ehm? Try http://www.promillerechner.net)
- inline tuple <> make_tuple () {
- tuple <> t;
- return t;
- }
-};
-
-#endif // !! BOOST_TUPLE_INCLUDED
diff --git a/3rdparty/assimp/code/ByteSwap.h b/3rdparty/assimp/code/ByteSwap.h
deleted file mode 100644
index 86ce9791..00000000
--- a/3rdparty/assimp/code/ByteSwap.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Helper class tp perform various byte oder swappings
- (e.g. little to big endian) */
-#ifndef AI_BYTESWAP_H_INC
-#define AI_BYTESWAP_H_INC
-
-#include "../include/aiAssert.h"
-#include "../include/aiTypes.h"
-
-#if _MSC_VER >= 1400
-#include <stdlib.h>
-#endif
-
-namespace Assimp {
-// --------------------------------------------------------------------------------------
-/** Defines some useful byte order swap routines.
- *
- * This is required to read big-endian model formats on little-endian machines,
- * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
-// --------------------------------------------------------------------------------------
-class ByteSwap
-{
- ByteSwap() {}
-
-public:
-
- // ----------------------------------------------------------------------
- /** Swap two bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap2(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
- *szOut = _byteswap_ushort(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[1]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** Swap four bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap4(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
- *szOut = _byteswap_ulong(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[3]);
- std::swap(szOut[1],szOut[2]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** Swap eight bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap8(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
- *szOut = _byteswap_uint64(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[7]);
- std::swap(szOut[1],szOut[6]);
- std::swap(szOut[2],szOut[5]);
- std::swap(szOut[3],szOut[4]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap a float. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(float* fOut) {
- Swap4(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap a double. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(double* fOut) {
- Swap8(fOut);
- }
-
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int16t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int16_t* fOut) {
- Swap2(fOut);
- }
-
- static inline void Swap(uint16_t* fOut) {
- Swap2(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int32t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int32_t* fOut){
- Swap4(fOut);
- }
-
- static inline void Swap(uint32_t* fOut){
- Swap4(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int64t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int64_t* fOut) {
- Swap8(fOut);
- }
-
- static inline void Swap(uint64_t* fOut) {
- Swap8(fOut);
- }
-
- // ----------------------------------------------------------------------
- //! Templatized ByteSwap
- //! \returns param tOut as swapped
- template<typename Type>
- static inline Type Swapped(Type tOut)
- {
- return _swapper<Type,sizeof(Type)>()(tOut);
- }
-
-private:
-
- template <typename T, size_t size> struct _swapper;
-};
-
-template <typename T> struct ByteSwap::_swapper<T,2> {
- T operator() (T tOut) {
- Swap2(&tOut);
- return tOut;
- }
-};
-
-template <typename T> struct ByteSwap::_swapper<T,4> {
- T operator() (T tOut) {
- Swap4(&tOut);
- return tOut;
- }
-};
-
-template <typename T> struct ByteSwap::_swapper<T,8> {
- T operator() (T tOut) {
- Swap8(&tOut);
- return tOut;
- }
-};
-
-} // Namespace Assimp
-
-
-// --------------------------------------------------------------------------------------
-// ByteSwap macros for BigEndian/LittleEndian support
-// --------------------------------------------------------------------------------------
-#if (defined AI_BUILD_BIG_ENDIAN)
-# define AI_LE(t) (t)
-# define AI_BE(t) ByteSwap::Swapped(t)
-# define AI_LSWAP2(p)
-# define AI_LSWAP4(p)
-# define AI_LSWAP8(p)
-# define AI_LSWAP2P(p)
-# define AI_LSWAP4P(p)
-# define AI_LSWAP8P(p)
-# define LE_NCONST const
-# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
-# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
-# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
-# define AI_SWAP2P(p) ByteSwap::Swap2((p))
-# define AI_SWAP4P(p) ByteSwap::Swap4((p))
-# define AI_SWAP8P(p) ByteSwap::Swap8((p))
-# define BE_NCONST
-#else
-# define AI_BE(t) (t)
-# define AI_LE(t) ByteSwap::Swapped(t)
-# define AI_SWAP2(p)
-# define AI_SWAP4(p)
-# define AI_SWAP8(p)
-# define AI_SWAP2P(p)
-# define AI_SWAP4P(p)
-# define AI_SWAP8P(p)
-# define BE_NCONST const
-# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
-# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
-# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
-# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
-# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
-# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
-# define LE_NCONST
-#endif
-
-
-
-#endif //!! AI_BYTESWAP_H_INC
diff --git a/3rdparty/assimp/code/COBLoader.cpp b/3rdparty/assimp/code/COBLoader.cpp
deleted file mode 100644
index 9639fc6b..00000000
--- a/3rdparty/assimp/code/COBLoader.cpp
+++ /dev/null
@@ -1,1278 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file COBLoader.cpp
- * @brief Implementation of the TrueSpace COB/SCN importer class.
- */
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-#include "COBLoader.h"
-#include "COBScene.h"
-
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
-
-using namespace Assimp;
-using namespace Assimp::COB;
-using namespace Assimp::Formatter;
-
-#define for_each BOOST_FOREACH
-
-
-static const float units[] = {
- 1000.f,
- 100.f,
- 1.f,
- 0.001f,
- 1.f/0.0254f,
- 1.f/0.3048f,
- 1.f/0.9144f,
- 1.f/1609.344f
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-COBImporter::COBImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-COBImporter::~COBImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "cob" || extension == "scn") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- const char* tokens[] = {"Caligary"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// List all extensions handled by this loader
-void COBImporter::GetExtensionList(std::set<std::string>& app)
-{
- app.insert("cob");
- app.insert("scn");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void COBImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void COBImporter::ThrowException(const std::string& msg)
-{
- throw DeadlyImportError("COB: "+msg);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void COBImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- COB::Scene scene;
- boost::scoped_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
-
- // check header
- char head[32];
- stream->CopyAndAdvance(head,32);
- if (strncmp(head,"Caligari ",9)) {
- ThrowException("Could not found magic id: `Caligari`");
- }
-
- DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
- void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
- if (head[16]!='L') {
- ThrowException("File is big-endian, which is not supported");
- }
-
- // load data into intermediate structures
- (this->*load)(scene,stream.get());
- if (scene.nodes.empty()) {
- ThrowException("No nodes loaded");
- }
-
- // sort faces by material indices
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- for_each(Face& f,mesh.faces) {
- mesh.temp_map[f.material].push_back(&f);
- }
- }
- }
-
- // count meshes
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
- pScene->mNumMeshes += mesh.temp_map.size();
- }
- }
- }
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
- pScene->mNumMeshes = 0;
-
- // count lights and cameras
- for_each(boost::shared_ptr< Node >& n,scene.nodes) {
- if (n->type == Node::TYPE_LIGHT) {
- ++pScene->mNumLights;
- }
- else if (n->type == Node::TYPE_CAMERA) {
- ++pScene->mNumCameras;
- }
- }
-
- if (pScene->mNumLights) {
- pScene->mLights = new aiLight*[pScene->mNumLights]();
- }
- if (pScene->mNumCameras) {
- pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
- }
- pScene->mNumLights = pScene->mNumCameras = 0;
-
- // resolve parents by their IDs and build the output graph
- boost::scoped_ptr<Node> root(new Group());
- for (size_t n = 0; n < scene.nodes.size(); ++n) {
- const Node& nn = *scene.nodes[n].get();
- if (nn.parent_id==0) {
- root->temp_children.push_back(&nn);
- }
-
- for (size_t m = n; m < scene.nodes.size(); ++m) {
- const Node& mm = *scene.nodes[m].get();
- if (mm.parent_id == nn.id) {
- nn.temp_children.push_back(&mm);
- }
- }
- }
-
- pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertTexture(boost::shared_ptr< Texture > tex, MaterialHelper* out, aiTextureType type)
-{
- const aiString path( tex->path );
- out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
- out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill)
-{
- aiNode* nd = new aiNode();
- nd->mName.Set(root.name);
- nd->mTransformation = root.transform;
-
- // Note to everybody believing Voodoo is appropriate here:
- // I know polymorphism, run as fast as you can ;-)
- if (Node::TYPE_MESH == root.type) {
- const Mesh& ndmesh = (const Mesh&)(root);
- if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
-
- typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
- for_each(const Entry& reflist,ndmesh.temp_map) {
- { // create mesh
- size_t n = 0;
- for_each(Face* f, reflist.second) {
- n += f->indices.size();
- }
- if (!n) {
- continue;
- }
- aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
- ++nd->mNumMeshes;
-
- outmesh->mVertices = new aiVector3D[n];
- outmesh->mTextureCoords[0] = new aiVector3D[n];
-
- outmesh->mFaces = new aiFace[reflist.second.size()]();
- for_each(Face* f, reflist.second) {
- if (f->indices.empty()) {
- continue;
- }
-
- aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
- fout.mIndices = new unsigned int[f->indices.size()];
-
- for_each(VertexIndex& v, f->indices) {
- if (v.pos_idx >= ndmesh.vertex_positions.size()) {
- ThrowException("Position index out of range");
- }
- if (v.uv_idx >= ndmesh.texture_coords.size()) {
- ThrowException("UV index out of range");
- }
- outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ];
- outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D(
- ndmesh.texture_coords[ v.uv_idx ].x,
- ndmesh.texture_coords[ v.uv_idx ].y,
- 0.f
- );
-
- fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
- }
- }
- outmesh->mMaterialIndex = fill->mNumMaterials;
- }{ // create material
- const Material* min = NULL;
- for_each(const Material& m, scin.materials) {
- if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
- min = &m;
- break;
- }
- }
- boost::scoped_ptr<const Material> defmat;
- if (!min) {
- DefaultLogger::get()->debug(format()<<"Could not resolve material index "
- <<reflist.first<<" - creating default material for this slot");
-
- defmat.reset(min=new Material());
- }
-
- MaterialHelper* mat = new MaterialHelper();
- fill->mMaterials[fill->mNumMaterials++] = mat;
-
- const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- if (int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
- mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- { int shader;
- switch(min->shader)
- {
- case Material::FLAT:
- shader = aiShadingMode_Gouraud;
- break;
-
- case Material::PHONG:
- shader = aiShadingMode_Phong;
- break;
-
- case Material::METAL:
- shader = aiShadingMode_CookTorrance;
- break;
-
- default:
- ai_assert(false); // shouldn't be here
- }
- mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
- if (shader != aiShadingMode_Gouraud) {
- mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
- }
- }
-
- mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
- mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);
-
- aiColor3D c = aiColor3D(min->rgb)*min->ks;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
-
- c = aiColor3D(min->rgb)*min->ka;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
-
- // convert textures if some exist.
- if (min->tex_color) {
- ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
- }
- if (min->tex_env) {
- ConvertTexture(min->tex_env ,mat,aiTextureType_UNKNOWN);
- }
- if (min->tex_bump) {
- ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
- }
- }
- }
- }
- }
- else if (Node::TYPE_LIGHT == root.type) {
- const Light& ndlight = (const Light&)(root);
- aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();
-
- outlight->mName.Set(ndlight.name);
- outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;
-
- outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
- outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);
-
- // XXX
- outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
- }
- else if (Node::TYPE_CAMERA == root.type) {
- const Camera& ndcam = (const Camera&)(root);
- aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();
-
- outcam->mName.Set(ndcam.name);
- }
-
- // add meshes
- if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for (unsigned int i = 0; i < nd->mNumMeshes;++i) {
- nd->mMeshes[i] = fill->mNumMeshes-i-1;
- }
- }
-
- // add children recursively
- nd->mChildren = new aiNode*[root.temp_children.size()]();
- for_each(const Node* n, root.temp_children) {
- (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
- }
-
- return nd;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read an ASCII file into the given scene data structure
-void COBImporter::ReadAsciiFile(Scene& out, StreamReaderLE* stream)
-{
- ChunkInfo ci;
- for (LineSplitter splitter(*stream);splitter;++splitter) {
-
- // add all chunks to be recognized here. /else ../ ommitted intentionally.
- if (splitter.match_start("PolH ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadPolH_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("BitM ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBitM_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Mat1 ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadMat1_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Grou ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadGrou_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Lght ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadLght_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Came ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadCame_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Bone ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBone_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Chan ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadChan_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Unit ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadUnit_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("END ")) {
- // we don't need this, but I guess there is a reason this
- // chunk has been implemented into COB for.
- return;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
-{
- const char* all_tokens[8];
- splitter.get_tokens(all_tokens);
-
- out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
- out.id = strtol10(all_tokens[3]);
- out.parent_id = strtol10(all_tokens[5]);
- out.size = strtol10s(all_tokens[7]);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
-{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if (nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
-
- // (HACK) - our current position in the stream is the beginning of the
- // head line of the next chunk. That's fine, but the caller is going
- // to call ++ on `splitter`, which we need to swallow to avoid
- // missing the next line.
- splitter.get_stream().IncPtr(nfo.size);
- splitter.swallow_next_increment();
- }
- else ThrowException(error);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message) {
- LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message) {
- LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message) {
- LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message) {
- LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->warn(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->error(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->info(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->debug(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
-{
- for (;splitter;++splitter) {
- if (splitter.match_start("Name")) {
- msh.name = std::string(splitter[1]);
-
- // make nice names by merging the dupe count
- std::replace(msh.name.begin(),msh.name.end(),
- ',','_');
- }
- else if (splitter.match_start("Transform")) {
- for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
- const char* s = splitter->c_str();
- for (unsigned int x = 0; x < 4; ++x) {
- SkipSpaces(&s);
- msh.transform[y][x] = fast_atof(&s);
- }
- }
- // we need the transform chunk, so we won't return until we have it.
- return;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in)
-{
- const char* rgb = *in;
- for (unsigned int i = 0; i < 3; ++i) {
- SkipSpaces(&rgb);
- if (*rgb == ',')++rgb;
- SkipSpaces(&rgb);
-
- fill[i] = fast_atof(&rgb);
- }
- *in = rgb;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
- }
-
- ++splitter;
- if (!splitter.match_start("mat# ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = strtol10(splitter[1]);
- ++splitter;
-
- if (!splitter.match_start("shader: ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
- std::string shader = std::string(splitter[1]);
- shader = shader.substr(0,shader.find_first_of(" \t"));
-
- if (shader == "metal") {
- mat.shader = Material::METAL;
- }
- else if (shader == "phong") {
- mat.shader = Material::PHONG;
- }
- else if (shader != "flat") {
- LogWarn_Ascii(splitter,format()<<
- "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
- }
-
- ++splitter;
- if (!splitter.match_start("rgb ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(mat.rgb,&rgb);
-
- ++splitter;
- if (!splitter.match_start("alpha ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* tokens[10];
- splitter.get_tokens(tokens);
-
- mat.alpha = fast_atof( tokens[1] );
- mat.ka = fast_atof( tokens[3] );
- mat.ks = fast_atof( tokens[5] );
- mat.exp = fast_atof( tokens[7] );
- mat.ior = fast_atof( tokens[9] );
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
- }
- ++splitter;
- if (!splitter.match_start("Units ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `Units` line in `Unit` chunk "<<nfo.id);
- return;
- }
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for_each(boost::shared_ptr< Node >& nd, out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=strtol10(splitter[1]);
-
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
- return;
- }
- }
- LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadChan_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
- }
-
- out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- if (splitter.match_start("Infinite ")) {
- msh.ltype = Light::INFINITE;
- }
- else if (splitter.match_start("Local ")) {
- msh.ltype = Light::LOCAL;
- }
- else if (splitter.match_start("Spot ")) {
- msh.ltype = Light::SPOT;
- }
- else {
- LogWarn_Ascii(splitter,format()<<
- "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
- msh.ltype = Light::SPOT;
- }
-
- ++splitter;
- if (!splitter.match_start("color ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `color` line in `Lght` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(msh.color ,&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"cone angle",10)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+10,&rgb);
- msh.angle = fast_atof(&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"inner angle",11)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+11,&rgb);
- msh.inner_angle = fast_atof(&rgb);
-
- // skip the rest for we can't handle this kind of physically-based lighting information.
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadCame_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 2) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Came");
- }
-
- out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // skip the next line, we don't know this differenciation between a
- // standard camera and a panoramic camera.
- ++splitter;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBone_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 5) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
- }
-
- out.nodes.push_back(boost::shared_ptr<Bone>(new Bone()));
- Bone& msh = (Bone&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // TODO
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadGrou_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
- }
-
- out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
- }
-
- out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // the chunk has a fixed order of components, but some are not interesting of us so
- // we're just looking for keywords in arbitrary order. The end of the chunk is
- // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
- for (;splitter;++splitter) {
- if (splitter.match_start("World Vertices")) {
- const unsigned int cnt = strtol10(splitter[2]);
- msh.vertex_positions.resize(cnt);
-
- for (unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector3D& v = msh.vertex_positions[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- SkipSpaces(&s);
- v.z = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Texture Vertices")) {
- const unsigned int cnt = strtol10(splitter[2]);
- msh.texture_coords.resize(cnt);
-
- for (unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector2D& v = msh.texture_coords[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Faces")) {
- const unsigned int cnt = strtol10(splitter[1]);
- msh.faces.reserve(cnt);
-
- for (unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
- if (splitter.match_start("Hole")) {
- LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
- continue;
- }
-
- if (!splitter.match_start("Face")) {
- ThrowException("Expected Face line");
- }
-
- msh.faces.push_back(Face());
- Face& face = msh.faces.back();
-
- face.indices.resize(strtol10(splitter[2]));
- face.flags = strtol10(splitter[4]);
- face.material = strtol10(splitter[6]);
-
- const char* s = (++splitter)->c_str();
- for (size_t i = 0; i < face.indices.size(); ++i) {
- if (!SkipSpaces(&s)) {
- ThrowException("Expected EOL token in Face entry");
- }
- if ('<' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- face.indices[i].pos_idx = strtol10(s,&s);
- if (',' != *s++) {
- ThrowException("Expected , token in Face entry");
- }
- face.indices[i].uv_idx = strtol10(s,&s);
- if ('>' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- }
- }
- if (nfo.version <= 4) {
- break;
- }
- }
- else if (splitter.match_start("DrawFlags")) {
- msh.draw_flags = strtol10(splitter[1]);
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if (nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
- }
-/*
- "\nThumbNailHdrSize %ld"
- "\nThumbHeader: %02hx 02hx %02hx "
- "\nColorBufSize %ld"
- "\nColorBufZipSize %ld"
- "\nZippedThumbnail: %02hx 02hx %02hx "
-*/
-
- const unsigned int head = strtol10((++splitter)[1]);
- if (head != sizeof(Bitmap::BitmapHeader)) {
- LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
- return;
- }
-
- /*union {
- Bitmap::BitmapHeader data;
- char opaq[sizeof Bitmap::BitmapHeader()];
- };*/
-// ReadHexOctets(opaq,head,(++splitter)[1]);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadString_Binary(std::string& out, StreamReaderLE& reader)
-{
- out.resize( reader.GetI2());
- for_each(char& c,out) {
- c = reader.GetI1();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBasicNodeInfo_Binary(Node& msh, StreamReaderLE& reader, const ChunkInfo& /*nfo*/)
-{
- const unsigned int dupes = reader.GetI2();
- ReadString_Binary(msh.name,reader);
-
- msh.name = format(msh.name)<<'_'<<dupes;
-
- // skip local axes for the moment
- reader.IncPtr(48);
-
- msh.transform = aiMatrix4x4();
- for (unsigned int y = 0; y < 3; ++y) {
- for (unsigned int x =0; x < 4; ++x) {
- msh.transform[y][x] = reader.GetF4();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkInfo& nfo, const char* name)
-{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if (nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
- reader.IncPtr(nfo.size);
- }
- else ThrowException(error);
-}
-
-// ------------------------------------------------------------------------------------------------
-// tiny utility guard to aid me at staying within chunk boundaries.
-class chunk_guard {
-
-public:
-
- chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
- : nfo(nfo)
- , reader(reader)
- , cur(reader.GetCurrentPos())
- {
- }
-
- ~chunk_guard() {
- // don't do anything if the size is not given
- if (nfo.size != static_cast<unsigned int>(-1)) {
- reader.IncPtr(static_cast<int>(nfo.size)-reader.GetCurrentPos()+cur);
- }
- }
-
-private:
-
- const COB::ChunkInfo& nfo;
- StreamReaderLE& reader;
- long cur;
-};
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
-{
- while (1) {
- std::string type;
- type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ;
-
- ChunkInfo nfo;
- nfo.version = reader -> GetI2()*10;
- nfo.version += reader -> GetI2();
-
- nfo.id = reader->GetI4();
- nfo.parent_id = reader->GetI4();
- nfo.size = reader->GetI4();
-
- if (type == "PolH") {
- ReadPolH_Binary(out,*reader,nfo);
- }
- else if (type == "BitM") {
- ReadBitM_Binary(out,*reader,nfo);
- }
- else if (type == "Grou") {
- ReadGrou_Binary(out,*reader,nfo);
- }
- else if (type == "Lght") {
- ReadLght_Binary(out,*reader,nfo);
- }
- else if (type == "Came") {
- ReadCame_Binary(out,*reader,nfo);
- }
- else if (type == "Mat1") {
- ReadMat1_Binary(out,*reader,nfo);
- }
- /* else if (type == "Bone") {
- ReadBone_Binary(out,*reader,nfo);
- }
- else if (type == "Chan") {
- ReadChan_Binary(out,*reader,nfo);
- }*/
- else if (type == "Unit") {
- ReadUnit_Binary(out,*reader,nfo);
- }
- else if (type == "OLay") {
- // ignore layer index silently.
- if (nfo.size != static_cast<unsigned int>(-1) ) {
- reader->IncPtr(nfo.size);
- }
- else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
- else if (type == "END ") {
- return;
- }
- else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"PolH");
- }
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(boost::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-
- msh.vertex_positions.resize(reader.GetI4());
- for_each(aiVector3D& v,msh.vertex_positions) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- v.z = reader.GetF4();
- }
-
- msh.texture_coords.resize(reader.GetI4());
- for_each(aiVector2D& v,msh.texture_coords) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- }
-
- const size_t numfuck = reader.GetI4();
- msh.faces.reserve(numfuck);
- for (size_t i = 0; i < numfuck; ++i) {
- // XXX backface culling flag is 0x10 in flags
-
- // hole?
- bool hole;
- if ((hole = (reader.GetI1() & 0x08) != 0)) {
- // XXX Basically this should just work fine - then triangulator
- // should output properly triangulated data even for polygons
- // with holes. Test data specific to COB is needed to confirm it.
- if (msh.faces.empty()) {
- ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
- }
- }
- else msh.faces.push_back(Face());
- Face& f = msh.faces.back();
-
- const size_t num = reader.GetI2();
- f.indices.reserve(f.indices.size() + num);
-
- if (!hole) {
- f.material = reader.GetI2();
- f.flags = 0;
- }
-
- for (size_t x = 0; x < num; ++x) {
- f.indices.push_back(VertexIndex());
-
- VertexIndex& v = f.indices.back();
- v.pos_idx = reader.GetI4();
- v.uv_idx = reader.GetI4();
- }
-
- if (hole) {
- std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
- }
- }
- if (nfo.version>4) {
- msh.draw_flags = reader.GetI4();
- }
- nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBitM_Binary(COB::Scene& /*out*/, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"BitM");
- }
-
- const chunk_guard cn(nfo,reader);
-
- const uint32_t len = reader.GetI4();
- reader.IncPtr(len);
-
- reader.GetI4();
- reader.IncPtr(reader.GetI4());
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"Mat1");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = reader.GetI2();
- switch(reader.GetI1()) {
- case 'f':
- mat.type = Material::FLAT;
- break;
- case 'p':
- mat.type = Material::PHONG;
- break;
- case 'm':
- mat.type = Material::METAL;
- break;
- default:
- LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
- mat.type = Material::FLAT;
- }
-
- switch(reader.GetI1()) {
- case 'f':
- mat.autofacet = Material::FACETED;
- break;
- case 'a':
- mat.autofacet = Material::AUTOFACETED;
- break;
- case 's':
- mat.autofacet = Material::SMOOTH;
- break;
- default:
- LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
- mat.autofacet = Material::FACETED;
- }
- mat.autofacet_angle = static_cast<float>(reader.GetI1());
-
- mat.rgb.r = reader.GetF4();
- mat.rgb.g = reader.GetF4();
- mat.rgb.b = reader.GetF4();
-
- mat.alpha = reader.GetF4();
- mat.ka = reader.GetF4();
- mat.ks = reader.GetF4();
- mat.exp = reader.GetF4();
- mat.ior = reader.GetF4();
-
- char id[2];
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
-
- if (id[0] == 'e' && id[1] == ':') {
- mat.tex_env.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_env->path,reader);
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 't' && id[1] == ':') {
- mat.tex_color.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_color->path,reader);
-
- mat.tex_color->transform.mTranslation.x = reader.GetF4();
- mat.tex_color->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_color->transform.mScaling.x = reader.GetF4();
- mat.tex_color->transform.mScaling.y = reader.GetF4();
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 'b' && id[1] == ':') {
- mat.tex_bump.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_bump->path,reader);
-
- mat.tex_bump->transform.mTranslation.x = reader.GetF4();
- mat.tex_bump->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_bump->transform.mScaling.x = reader.GetF4();
- mat.tex_bump->transform.mScaling.y = reader.GetF4();
-
- // skip amplitude for I don't know its purpose.
- reader.GetF4();
- }
- reader.IncPtr(-2);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Came");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(boost::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-
- // the rest is not interesting for us, so we skip over it.
- if (nfo.version > 1) {
- if (reader.GetI2()==512) {
- reader.IncPtr(42);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Lght");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(boost::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Grou");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(boost::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if (nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"Unit");
- }
-
- const chunk_guard cn(nfo,reader);
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for_each(boost::shared_ptr< Node >& nd, out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=reader.GetI2();
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
-
- return;
- }
- }
- LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
-}
-
-
-#endif
diff --git a/3rdparty/assimp/code/COBLoader.h b/3rdparty/assimp/code/COBLoader.h
deleted file mode 100644
index 976fc608..00000000
--- a/3rdparty/assimp/code/COBLoader.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file COBLoader.h
- * @brief Declaration of the TrueSpace (*.cob,*.scn) importer class.
- */
-#ifndef INCLUDED_AI_COB_LOADER_H
-#define INCLUDED_AI_COB_LOADER_H
-
-#include "BaseImporter.h"
-namespace Assimp {
- class LineSplitter;
-
- // TinyFormatter.h
- namespace Formatter {
- template <typename T,typename TR, typename A> class basic_formatter;
- typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
- }
-
- // COBScene.h
- namespace COB {
- struct ChunkInfo;
- struct Node;
- struct Scene;
- }
-
-// -------------------------------------------------------------------------------------------
-/** Importer class to load TrueSpace files (cob,scn) up to v6.
- *
- * Currently relatively limited, loads only ASCII files and needs more test coverage. */
-// -------------------------------------------------------------------------------------------
-class COBImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
-
- /** Constructor to be privately used by Importer */
- COBImporter();
-
- /** Destructor, private as well */
- ~COBImporter();
-
-public:
-
- // --------------------
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // --------------------
- void GetExtensionList(std::set<std::string>& app);
-
- // --------------------
- void SetupProperties(const Importer* pImp);
-
- // --------------------
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- // -------------------------------------------------------------------
- /** Prepend 'COB: ' and throw msg.*/
- static void ThrowException(const std::string& msg);
-
- // -------------------------------------------------------------------
- /** @brief Read from an ascii scene/object file
- * @param out Receives output data.
- * @param stream Stream to read from. */
- void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
-
- // -------------------------------------------------------------------
- /** @brief Read from a binary scene/object file
- * @param out Receives output data.
- * @param stream Stream to read from. */
- void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
-
-
-private:
-
- // Conversion to Assimp output format
-
- aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
-
-private:
-
- // ASCII file support
-
- void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
- void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
- void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
-
- void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
-
-
- // ASCII file logging stuff to add proper line numbers to messages
-
- static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
- static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
- static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
- static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
-
- static void LogWarn_Ascii (const Formatter::format& message);
- static void LogError_Ascii (const Formatter::format& message);
- static void LogInfo_Ascii (const Formatter::format& message);
- static void LogDebug_Ascii (const Formatter::format& message);
-
-
- // Binary file support
-
- void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
- void ReadString_Binary(std::string& out, StreamReaderLE& reader);
- void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
-
- void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
-
-
-}; // !class COBImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/COBScene.h b/3rdparty/assimp/code/COBScene.h
deleted file mode 100644
index 2ce054b6..00000000
--- a/3rdparty/assimp/code/COBScene.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file COBScene.h
-* @brief Utilities for the COB importer.
-*/
-#ifndef INCLUDED_AI_COB_SCENE_H
-#define INCLUDED_AI_COB_SCENE_H
-
-#include <boost/shared_ptr.hpp>
-#include "BaseImporter.h"
-
-namespace Assimp {
- namespace COB {
-
-// ------------------
-/** Represents a single vertex index in a face */
-struct VertexIndex
-{
- // intentionally uninitialized
- unsigned int pos_idx,uv_idx;
-};
-
-// ------------------
-/** COB Face data structure */
-struct Face
-{
- // intentionally uninitialized
- unsigned int material, flags;
- std::vector<VertexIndex> indices;
-};
-
-// ------------------
-/** COB chunk header information */
-struct ChunkInfo
-{
- enum {NO_SIZE=0xffffffff};
-
- ChunkInfo ()
- : id (0)
- , parent_id (0)
- , version (0)
- , size (NO_SIZE)
- {}
-
- // Id of this chunk, unique within file
- unsigned int id;
-
- // and the corresponding parent
- unsigned int parent_id;
-
- // version. v1.23 becomes 123
- unsigned int version;
-
- // chunk size in bytes, only relevant for binary files
- // NO_SIZE is also valid.
- unsigned int size;
-/*
- ChunkInfo& ChunkInfo::operator=(const ChunkInfo &rhs) {
- // Only do assignment if RHS is a different object from this.
- if (this != &rhs) {
- this->id=rhs.id;
- this->parent_id=rhs.parent_id;
- this->version=rhs.version;
- this->size=rhs.size;
- }
-
- return *this;
- }*/
-};
-
-// ------------------
-/** A node in the scenegraph */
-struct Node : public ChunkInfo
-{
- using ChunkInfo::operator=;
- enum Type {
- TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
- };
-
- virtual ~Node() {}
- Node(Type type) : type(type), unit_scale(1.f){}
-
- Type type;
-
- // used during resolving
- typedef std::deque<const Node*> ChildList;
- mutable ChildList temp_children;
-
- // unique name
- std::string name;
-
- // local mesh transformation
- aiMatrix4x4 transform;
-
- // scaling for this node to get to the metric system
- float unit_scale;
-};
-
-// ------------------
-/** COB Mesh data structure */
-struct Mesh : public Node
-{
- using ChunkInfo::operator=;
- enum DrawFlags {
- SOLID = 0x1,
- TRANS = 0x2,
- WIRED = 0x4,
- BBOX = 0x8,
- HIDE = 0x10
- };
-
- Mesh()
- : Node(TYPE_MESH)
- , draw_flags(SOLID)
- {}
-
- // vertex elements
- std::vector<aiVector2D> texture_coords;
- std::vector<aiVector3D> vertex_positions;
-
- // face data
- std::vector<Face> faces;
-
- // misc. drawing flags
- unsigned int draw_flags;
-
- // used during resolving
- typedef std::deque<Face*> FaceRefList;
- typedef std::map< unsigned int,FaceRefList > TempMap;
- TempMap temp_map;
-};
-
-// ------------------
-/** COB Group data structure */
-struct Group : public Node
-{
- using ChunkInfo::operator=;
- Group() : Node(TYPE_GROUP) {}
-};
-
-// ------------------
-/** COB Bone data structure */
-struct Bone : public Node
-{
- using ChunkInfo::operator=;
- Bone() : Node(TYPE_BONE) {}
-};
-
-// ------------------
-/** COB Light data structure */
-struct Light : public Node
-{
- enum LightType {
- SPOT,LOCAL,INFINITE
- };
-
- using ChunkInfo::operator=;
- Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
-
- aiColor3D color;
- float angle,inner_angle;
-
- LightType ltype;
-};
-
-// ------------------
-/** COB Camera data structure */
-struct Camera : public Node
-{
- using ChunkInfo::operator=;
- Camera() : Node(TYPE_CAMERA) {}
-};
-
-// ------------------
-/** COB Texture data structure */
-struct Texture
-{
- std::string path;
- aiUVTransform transform;
-};
-
-// ------------------
-/** COB Material data structure */
-struct Material : ChunkInfo
-{
- using ChunkInfo::operator=;
- enum Shader {
- FLAT,PHONG,METAL
- };
-
- enum AutoFacet {
- FACETED,AUTOFACETED,SMOOTH
- };
-
- Material() : alpha(),exp(),ior(),ka(),ks(1.f),
- matnum(0xffffffff),
- shader(FLAT),autofacet(FACETED),
- autofacet_angle()
- {}
-
- std::string type;
-
- aiColor3D rgb;
- float alpha, exp, ior,ka,ks;
-
- unsigned int matnum;
- Shader shader;
-
- AutoFacet autofacet;
- float autofacet_angle;
-
- boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
-};
-
-// ------------------
-/** Embedded bitmap, for instance for the thumbnail image */
-struct Bitmap : ChunkInfo
-{
- Bitmap() : orig_size() {}
- struct BitmapHeader
- {
- };
-
- BitmapHeader head;
- size_t orig_size;
- std::vector<char> buff_zipped;
-};
-
-typedef std::deque< boost::shared_ptr<Node> > NodeList;
-typedef std::vector< Material > MaterialList;
-
-// ------------------
-/** Represents a master COB scene, even if we loaded just a single COB file */
-struct Scene
-{
- NodeList nodes;
- MaterialList materials;
-
- // becomes *0 later
- Bitmap thumbnail;
-};
-
- } // end COB
-} // end Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/CSMLoader.cpp b/3rdparty/assimp/code/CSMLoader.cpp
deleted file mode 100644
index 5e91fea3..00000000
--- a/3rdparty/assimp/code/CSMLoader.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2009, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file CSMLoader.cpp
- * Implementation of the CSM importer class.
- */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-
-#include "CSMLoader.h"
-#include "SkeletonMeshBuilder.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-CSMImporter::CSMImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CSMImporter::~CSMImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if ( extension == "csm")
- return true;
-
- if ((checkSig || !extension.length()) && pIOHandler) {
- const char* tokens[] = {"$Filename"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-void CSMImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("csm");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void CSMImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void CSMImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- aiAnimation* anim = new aiAnimation();
- int first = 0, last = 0x00ffffff;
-
- // now process the file and look out for '$' sections
- while (1) {
- SkipSpaces(&buffer);
- if ('\0' == *buffer)
- break;
-
- if ('$' == *buffer) {
- ++buffer;
- if (TokenMatchI(buffer,"firstframe",10)) {
- SkipSpaces(&buffer);
- first = strtol10s(buffer,&buffer);
- }
- else if (TokenMatchI(buffer,"lastframe",9)) {
- SkipSpaces(&buffer);
- last = strtol10s(buffer,&buffer);
- }
- else if (TokenMatchI(buffer,"rate",4)) {
- SkipSpaces(&buffer);
- float d;
- buffer = fast_atof_move(buffer,d);
- anim->mTicksPerSecond = d;
- }
- else if (TokenMatchI(buffer,"order",5)) {
- std::vector< aiNodeAnim* > anims_temp;
- anims_temp.reserve(30);
- while (1) {
- SkipSpaces(&buffer);
- if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
- break; // next section
-
- // Construct a new node animation channel and setup its name
- anims_temp.push_back(new aiNodeAnim());
- aiNodeAnim* nda = anims_temp.back();
-
- char* ot = nda->mNodeName.data;
- while (!IsSpaceOrNewLine(*buffer))
- *ot++ = *buffer++;
-
- *ot = '\0';
- nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
- }
-
- anim->mNumChannels = anims_temp.size();
- if (!anim->mNumChannels)
- throw DeadlyImportError("CSM: Empty $order section");
-
- // copy over to the output animation
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
- ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
- }
- else if (TokenMatchI(buffer,"points",6)) {
- if (!anim->mNumChannels)
- throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
-
- // If we know how many frames we'll read, we can preallocate some storage
- unsigned int alloc = 100;
- if (last != 0x00ffffff)
- {
- alloc = last-first;
- alloc += alloc>>2u; // + 25%
- for (unsigned int i = 0; i < anim->mNumChannels;++i)
- anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
- }
-
- unsigned int filled = 0;
-
- // Now read all point data.
- while (1) {
- SkipSpaces(&buffer);
- if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
- break; // next section
- }
-
- // read frame
- const int frame = ::strtol10(buffer,&buffer);
- last = std::max(frame,last);
- first = std::min(frame,last);
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
-
- aiNodeAnim* s = anim->mChannels[i];
- if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
-
- aiVectorKey* old = s->mPositionKeys;
- s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
- ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
- delete[] old;
- }
-
- // read x,y,z
- if (!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
-
- if (TokenMatchI(buffer, "DROPOUT", 7)) {
- // seems this is invalid marker data; at least the doc says it's possible
- DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
- }
- else {
- aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
- sub->mTime = (double)frame;
- buffer = fast_atof_move(buffer, (float&)sub->mValue.x);
-
- if (!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
- buffer = fast_atof_move(buffer, (float&)sub->mValue.y);
-
- if (!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
- buffer = fast_atof_move(buffer, (float&)sub->mValue.z);
-
- ++s->mNumPositionKeys;
- }
- }
-
- // update allocation granularity
- if (filled == alloc)
- alloc *= 2;
-
- ++filled;
- }
- // all channels must be complete in order to continue safely.
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
-
- if (!anim->mChannels[i]->mNumPositionKeys)
- throw DeadlyImportError("CSM: Invalid marker track");
- }
- }
- }
- else {
- // advance to the next line
- SkipLine(&buffer);
- }
- }
-
- // Setup a proper animation duration
- anim->mDuration = last - std::min( first, 0 );
-
- // build a dummy root node with the tiny markers as children
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("$CSM_DummyRoot");
-
- pScene->mRootNode->mNumChildren = anim->mNumChannels;
- pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
-
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* na = anim->mChannels[i];
-
- aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
- nd->mName = anim->mChannels[i]->mNodeName;
- nd->mParent = pScene->mRootNode;
-
- aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
- }
-
- // Store the one and only animation in the scene
- pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
- pScene->mAnimations[0] = anim;
- anim->mName.Set("$CSM_MasterAnim");
-
- // mark the scene as incomplete and run SkeletonMeshBuilder on it
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
-}
-
-#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER
diff --git a/3rdparty/assimp/code/CSMLoader.h b/3rdparty/assimp/code/CSMLoader.h
deleted file mode 100644
index f3d1c458..00000000
--- a/3rdparty/assimp/code/CSMLoader.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file CSMLoader.h
- * Declaration of the CharacterStudio Motion importer class.
- */
-#ifndef INCLUDED_AI_CSM_LOADER_H
-#define INCLUDED_AI_CSM_LOADER_H
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class to load MOCAPs in CharacterStudio Motion format.
- *
- * A very rudimentary loader for the moment. No support for the hierarchy,
- * every marker is returned as child of root.
- *
- * Link to file format specification:
- * <max_8_dvd>\samples\Motion\Docs\CSM.rtf
-*/
-class CSMImporter : public BaseImporter
-{
- friend class Importer;
-protected:
- /** Constructor to be privately used by Importer */
- CSMImporter();
-
- /** Destructor, private as well */
- ~CSMImporter();
-
-public:
- // -------------------------------------------------------------------
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-}; // end of class CSMImporter
-} // end of namespace Assimp
-#endif // AI_AC3DIMPORTER_H_INC
-
diff --git a/3rdparty/assimp/code/CalcTangentsProcess.cpp b/3rdparty/assimp/code/CalcTangentsProcess.cpp
deleted file mode 100644
index 83ec00a5..00000000
--- a/3rdparty/assimp/code/CalcTangentsProcess.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to calculate
- * tangents and bitangents for all imported meshes
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "CalcTangentsProcess.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-CalcTangentsProcess::CalcTangentsProcess()
-{
- this->configMaxAngle = AI_DEG_TO_RAD(45.f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CalcTangentsProcess::~CalcTangentsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_CalcTangentSpace) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void CalcTangentsProcess::SetupProperties(const Importer* pImp)
-{
- // get the current value of the property
- this->configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
- this->configMaxAngle = std::max(std::min(this->configMaxAngle,45.0f),0.0f);
- this->configMaxAngle = AI_DEG_TO_RAD(this->configMaxAngle);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void CalcTangentsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("CalcTangentsProcess begin");
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- if (ProcessMesh( pScene->mMeshes[a],a))bHas = true;
-
- if (bHas)DefaultLogger::get()->debug("CalcTangentsProcess finished. Tangents have been calculated");
- else DefaultLogger::get()->debug("CalcTangentsProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Calculates tangents and bitangents for the given mesh
-bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
-{
- // we assume that the mesh is still in the verbose vertex format where each face has its own set
- // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
- // assert() it here.
- //assert( must be verbose, dammit);
-
- if (pMesh->mTangents) // thisimplies that mBitangents is also there
- return false;
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
- {
- DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
- return false;
- }
-
- // what we can check, though, is if the mesh has normals and texture coord. That's a requirement
- if ( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL)
- {
- DefaultLogger::get()->error("Unable to compute tangents: UV0 and normals must be there ");
- return false;
- }
- const float angleEpsilon = 0.9999f;
-
- std::vector<bool> vertexDone( pMesh->mNumVertices, false);
- const float qnan = get_qnan();
-
- // create space for the tangents and bitangents
- pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
- pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
-
- const aiVector3D* meshPos = pMesh->mVertices;
- const aiVector3D* meshNorm = pMesh->mNormals;
- const aiVector3D* meshTex = pMesh->mTextureCoords[0];
- aiVector3D* meshTang = pMesh->mTangents;
- aiVector3D* meshBitang = pMesh->mBitangents;
-
- // calculate the tangent and bitangent for every face
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3)
- {
- // There are less than three indices, thus the tangent vector
- // is not defined. We are finished with these vertices now,
- // their tangent vectors are set to qnan.
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- register unsigned int idx = face.mIndices[i];
- vertexDone [idx] = true;
- meshTang [idx] = qnan;
- meshBitang [idx] = qnan;
- }
-
- continue;
- }
-
- // triangle or polygon... we always use only the first three indices. A polygon
- // is supposed to be planar anyways....
- // FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
- const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
-
- // position differences p1->p2 and p1->p3
- aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
-
- // texture offset p1->p2 and p1->p3
- float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
- float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
- float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
-
- // tangent points in the direction where to positive X axis of the texture coords would point in model space
- // bitangents points along the positive Y axis of the texture coords, respectively
- aiVector3D tangent, bitangent;
- tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
- tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
- tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
- bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
- bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
- bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
-
- // store for every vertex of that face
- for ( unsigned int b = 0; b < face.mNumIndices; b++)
- {
- unsigned int p = face.mIndices[b];
-
- // project tangent and bitangent into the plane formed by the vertex' normal
- aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
- aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
- localTangent.Normalize(); localBitangent.Normalize();
-
- // and write it into the mesh.
- meshTang[p] = localTangent;
- meshBitang[p] = localBitangent;
- }
- }
-
-
- // create a helper to quickly find locally close vertices among the vertex array
- // FIX: check whether we can reuse the SpatialSort of a previous step
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
- float posEpsilon;
- if (shared)
- {
- std::vector<std::pair<SpatialSort,float> >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf)
- {
- std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
- vertexFinder = &blubb.first;
- posEpsilon = blubb.second;;
- }
- }
- if (!vertexFinder)
- {
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- posEpsilon = ComputePositionEpsilon(pMesh);
- }
- std::vector<unsigned int> verticesFound;
-
- const float fLimit = cosf(this->configMaxAngle);
- std::vector<unsigned int> closeVertices;
-
- // in the second pass we now smooth out all tangents and bitangents at the same local position
- // if they are not too far off.
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- {
- if ( vertexDone[a])
- continue;
-
- const aiVector3D& origPos = pMesh->mVertices[a];
- const aiVector3D& origNorm = pMesh->mNormals[a];
- const aiVector3D& origTang = pMesh->mTangents[a];
- const aiVector3D& origBitang = pMesh->mBitangents[a];
- closeVertices.clear();
-
- // find all vertices close to that position
- vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
-
- closeVertices.reserve (verticesFound.size()+5);
- closeVertices.push_back( a);
-
- // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
- for ( unsigned int b = 0; b < verticesFound.size(); b++)
- {
- unsigned int idx = verticesFound[b];
- if ( vertexDone[idx])
- continue;
- if ( meshNorm[idx] * origNorm < angleEpsilon)
- continue;
- if ( meshTang[idx] * origTang < fLimit)
- continue;
- if ( meshBitang[idx] * origBitang < fLimit)
- continue;
-
- // it's similar enough -> add it to the smoothing group
- closeVertices.push_back( idx);
- vertexDone[idx] = true;
- }
-
- // smooth the tangents and bitangents of all vertices that were found to be close enough
- aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
- for ( unsigned int b = 0; b < closeVertices.size(); ++b)
- {
- smoothTangent += meshTang[ closeVertices[b] ];
- smoothBitangent += meshBitang[ closeVertices[b] ];
- }
- smoothTangent.Normalize();
- smoothBitangent.Normalize();
-
- // and write it back into all affected tangents
- for ( unsigned int b = 0; b < closeVertices.size(); ++b)
- {
- meshTang[ closeVertices[b] ] = smoothTangent;
- meshBitang[ closeVertices[b] ] = smoothBitangent;
- }
- }
- return true;
-}
diff --git a/3rdparty/assimp/code/CalcTangentsProcess.h b/3rdparty/assimp/code/CalcTangentsProcess.h
deleted file mode 100644
index 189710ff..00000000
--- a/3rdparty/assimp/code/CalcTangentsProcess.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines a post processing step to calculate tangents and
- bitangents on all imported meshes.*/
-#ifndef AI_CALCTANGENTSPROCESS_H_INC
-#define AI_CALCTANGENTSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
- * of all meshes. It is expected to be run before the JoinVerticesProcess runs
- * because the joining of vertices also considers tangents and bitangents for
- * uniqueness.
- */
-class ASSIMP_API CalcTangentsProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- CalcTangentsProcess();
-
- /** Destructor, private as well */
- ~CalcTangentsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-
- // setter for configMaxAngle
- inline void SetMaxSmoothAngle(float f)
- {
- configMaxAngle =f;
- }
-
-protected:
-
- // -------------------------------------------------------------------
- /** Calculates tangents and bitangents for a specific mesh.
- * @param pMesh The mesh to process.
- * @param meshIndex Index of the mesh
- */
- bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-private:
-
- /** Configuration option: maximum smoothing angle, in radians*/
- float configMaxAngle;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/3rdparty/assimp/code/ColladaHelper.h b/3rdparty/assimp/code/ColladaHelper.h
deleted file mode 100644
index ddf14990..00000000
--- a/3rdparty/assimp/code/ColladaHelper.h
+++ /dev/null
@@ -1,601 +0,0 @@
-/** Helper structures for the Collada loader */
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef AI_COLLADAHELPER_H_INC
-#define AI_COLLADAHELPER_H_INC
-
-namespace Assimp {
-namespace Collada {
-
-/** Collada file versions which evolved during the years ... */
-enum FormatVersion
-{
- FV_1_5_n,
- FV_1_4_n,
- FV_1_3_n
-};
-
-
-/** Transformation types that can be applied to a node */
-enum TransformType
-{
- TF_LOOKAT,
- TF_ROTATE,
- TF_TRANSLATE,
- TF_SCALE,
- TF_SKEW,
- TF_MATRIX
-};
-
-/** Different types of input data to a vertex or face */
-enum InputType
-{
- IT_Invalid,
- IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
- IT_Position,
- IT_Normal,
- IT_Texcoord,
- IT_Color,
- IT_Tangent,
- IT_Bitangent
-};
-
-/** Contains all data for one of the different transformation types */
-struct Transform
-{
- std::string mID; ///< SID of the transform step, by which anim channels address their target node
- TransformType mType;
- float f[16]; ///< Interpretation of data depends on the type of the transformation
-};
-
-/** A collada camera. */
-struct Camera
-{
- Camera()
- : mOrtho (false)
- , mHorFov (10e10f)
- , mVerFov (10e10f)
- , mAspect (10e10f)
- , mZNear (0.1f)
- , mZFar (1000.f)
- {}
-
- // Name of camera
- std::string mName;
-
- // True if it is an orthografic camera
- bool mOrtho;
-
- //! Horizontal field of view in degrees
- float mHorFov;
-
- //! Vertical field of view in degrees
- float mVerFov;
-
- //! Screen aspect
- float mAspect;
-
- //! Near& far z
- float mZNear, mZFar;
-};
-
-#define aiLightSource_AMBIENT 0xdeaddead
-
-/** A collada light source. */
-struct Light
-{
- Light()
- : mAttConstant (1.f)
- , mAttLinear (0.f)
- , mAttQuadratic (0.f)
- , mFalloffAngle (180.f)
- , mFalloffExponent (0.f)
- , mPenumbraAngle (10e10f)
- , mOuterAngle (10e10f)
- , mIntensity (1.f)
- {}
-
- //! Type of the light source aiLightSourceType + ambient
- unsigned int mType;
-
- //! Color of the light
- aiColor3D mColor;
-
- //! Light attenuation
- float mAttConstant,mAttLinear,mAttQuadratic;
-
- //! Spot light falloff
- float mFalloffAngle;
- float mFalloffExponent;
-
- // -----------------------------------------------------
- // FCOLLADA extension from here
-
- //! ... related stuff from maja and max extensions
- float mPenumbraAngle;
- float mOuterAngle;
-
- //! Common light intensity
- float mIntensity;
-};
-
-/** Short vertex index description */
-struct InputSemanticMapEntry
-{
- InputSemanticMapEntry()
- : mSet (0)
- {}
-
- //! Index of set, optional
- unsigned int mSet;
-
- //! Name of referenced vertex input
- InputType mType;
-};
-
-/** Table to map from effect to vertex input semantics */
-struct SemanticMappingTable
-{
- //! Name of material
- std::string mMatName;
-
- //! List of semantic map commands, grouped by effect semantic name
- std::map<std::string, InputSemanticMapEntry> mMap;
-
- //! For std::find
- bool operator == (const std::string& s) const {
- return s == mMatName;
- }
-};
-
-/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
- * The ID refers to either a mesh or a controller which specifies the mesh
- */
-struct MeshInstance
-{
- ///< ID of the mesh or controller to be instanced
- std::string mMeshOrController;
-
- ///< Map of materials by the subgroup ID they're applied to
- std::map<std::string, SemanticMappingTable> mMaterials;
-};
-
-/** A reference to a camera inside a node*/
-struct CameraInstance
-{
- ///< ID of the camera
- std::string mCamera;
-};
-
-/** A reference to a light inside a node*/
-struct LightInstance
-{
- ///< ID of the camera
- std::string mLight;
-};
-
-/** A reference to a node inside a node*/
-struct NodeInstance
-{
- ///< ID of the node
- std::string mNode;
-};
-
-/** A node in a scene hierarchy */
-struct Node
-{
- std::string mName;
- std::string mID;
- std::string mSID;
- Node* mParent;
- std::vector<Node*> mChildren;
-
- /** Operations in order to calculate the resulting transformation to parent. */
- std::vector<Transform> mTransforms;
-
- /** Meshes at this node */
- std::vector<MeshInstance> mMeshes;
-
- /** Lights at this node */
- std::vector<LightInstance> mLights;
-
- /** Cameras at this node */
- std::vector<CameraInstance> mCameras;
-
- /** Node instances at this node */
- std::vector<NodeInstance> mNodeInstances;
-
- /** Rootnodes: Name of primary camera, if any */
- std::string mPrimaryCamera;
-
- //! Constructor. Begin with a zero parent
- Node() {
- mParent = NULL;
- }
-
- //! Destructor: delete all children subsequently
- ~Node() {
- for ( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
- delete *it;
- }
-};
-
-/** Data source array: either floats or strings */
-struct Data
-{
- bool mIsStringArray;
- std::vector<float> mValues;
- std::vector<std::string> mStrings;
-};
-
-/** Accessor to a data array */
-struct Accessor
-{
- size_t mCount; // in number of objects
- size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
- size_t mOffset; // in number of values
- size_t mStride; // Stride in number of values
- std::vector<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, thats XYZ, for a color RGBA and so on.
- // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
- std::string mSource; // URL of the source array
- mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
-
- Accessor()
- {
- mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL;
- mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
- }
-};
-
-/** A single face in a mesh */
-struct Face
-{
- std::vector<size_t> mIndices;
-};
-
-/** An input channel for mesh data, referring to a single accessor */
-struct InputChannel
-{
- InputType mType; // Type of the data
- size_t mIndex; // Optional index, if multiple sets of the same data type are given
- size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
- std::string mAccessor; // ID of the accessor where to read the actual values from.
- mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
-
- InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
-};
-
-/** Subset of a mesh with a certain material */
-struct SubMesh
-{
- std::string mMaterial; ///< subgroup identifier
- size_t mNumFaces; ///< number of faces in this submesh
-};
-
-/** Contains data for a single mesh */
-struct Mesh
-{
- Mesh()
- {
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- mNumUVComponents[i] = 2;
- }
-
- // just to check if there's some sophisticated addressing involved...
- // which we don't support, and therefore should warn about.
- std::string mVertexID;
-
- // Vertex data addressed by vertex indices
- std::vector<InputChannel> mPerVertexData;
-
- // actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
- std::vector<aiVector3D> mPositions;
- std::vector<aiVector3D> mNormals;
- std::vector<aiVector3D> mTangents;
- std::vector<aiVector3D> mBitangents;
- std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- // Faces. Stored are only the number of vertices for each face.
- // 1 == point, 2 == line, 3 == triangle, 4+ == poly
- std::vector<size_t> mFaceSize;
-
- // Position indices for all faces in the sequence given in mFaceSize -
- // necessary for bone weight assignment
- std::vector<size_t> mFacePosIndices;
-
- // Submeshes in this mesh, each with a given material
- std::vector<SubMesh> mSubMeshes;
-};
-
-/** Which type of primitives the ReadPrimitives() function is going to read */
-enum PrimitiveType
-{
- Prim_Invalid,
- Prim_Lines,
- Prim_LineStrip,
- Prim_Triangles,
- Prim_TriStrips,
- Prim_TriFans,
- Prim_Polylist,
- Prim_Polygon
-};
-
-/** A skeleton controller to deform a mesh with the use of joints */
-struct Controller
-{
- // the URL of the mesh deformed by the controller.
- std::string mMeshId;
-
- // accessor URL of the joint names
- std::string mJointNameSource;
-
- ///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases
- float mBindShapeMatrix[16];
-
- // accessor URL of the joint inverse bind matrices
- std::string mJointOffsetMatrixSource;
-
- // input channel: joint names.
- InputChannel mWeightInputJoints;
- // input channel: joint weights
- InputChannel mWeightInputWeights;
-
- // Number of weights per vertex.
- std::vector<size_t> mWeightCounts;
-
- // JointIndex-WeightIndex pairs for all vertices
- std::vector< std::pair<size_t, size_t> > mWeights;
-};
-
-/** A collada material. Pretty much the only member is a reference to an effect. */
-struct Material
-{
- std::string mEffect;
-};
-
-/** Type of the effect param */
-enum ParamType
-{
- Param_Sampler,
- Param_Surface
-};
-
-/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
-struct EffectParam
-{
- ParamType mType;
- std::string mReference; // to which other thing the param is referring to.
-};
-
-/** Shading type supported by the standard effect spec of Collada */
-enum ShadeType
-{
- Shade_Invalid,
- Shade_Constant,
- Shade_Lambert,
- Shade_Phong,
- Shade_Blinn
-};
-
-/** Represents a texture sampler in collada */
-struct Sampler
-{
- Sampler()
- : mWrapU (true)
- , mWrapV (true)
- , mMirrorU ()
- , mMirrorV ()
- , mOp (aiTextureOp_Multiply)
- , mUVId (0xffffffff)
- , mWeighting (1.f)
- , mMixWithPrevious (1.f)
- {}
-
- /** Name of image reference
- */
- std::string mName;
-
- /** Wrap U?
- */
- bool mWrapU;
-
- /** Wrap V?
- */
- bool mWrapV;
-
- /** Mirror U?
- */
- bool mMirrorU;
-
- /** Mirror V?
- */
- bool mMirrorV;
-
- /** Blend mode
- */
- aiTextureOp mOp;
-
- /** UV transformation
- */
- aiUVTransform mTransform;
-
- /** Name of source UV channel
- */
- std::string mUVChannel;
-
- /** Resolved UV channel index or 0xffffffff if not known
- */
- unsigned int mUVId;
-
- // OKINO/MAX3D extensions from here
- // -------------------------------------------------------
-
- /** Weighting factor
- */
- float mWeighting;
-
- /** Mixing factor from OKINO
- */
- float mMixWithPrevious;
-};
-
-/** A collada effect. Can contain about anything according to the Collada spec,
- but we limit our version to a reasonable subset. */
-struct Effect
-{
- // Shading mode
- ShadeType mShadeType;
-
- // Colors
- aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
- mTransparent, mReflective;
-
- // Textures
- Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
- mTexTransparent, mTexBump, mTexReflective;
-
- // Scalar factory
- float mShininess, mRefractIndex, mReflectivity;
- float mTransparency;
-
- // local params referring to each other by their SID
- typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
- ParamLibrary mParams;
-
- // MAX3D extensions
- // ---------------------------------------------------------
- // Double-sided?
- bool mDoubleSided, mWireframe, mFaceted;
-
- Effect()
- : mShadeType (Shade_Phong)
- , mEmissive ( 0, 0, 0, 1)
- , mAmbient ( 0.1f, 0.1f, 0.1f, 1)
- , mDiffuse ( 0.6f, 0.6f, 0.6f, 1)
- , mSpecular ( 0.4f, 0.4f, 0.4f, 1)
- , mTransparent ( 0, 0, 0, 1)
- , mShininess (10.0f)
- , mRefractIndex (1.f)
- , mReflectivity (1.f)
- , mTransparency (0.f)
- , mDoubleSided (false)
- , mWireframe (false)
- , mFaceted (false)
- {
- }
-};
-
-/** An image, meaning texture */
-struct Image
-{
- std::string mFileName;
-
- /** If image file name is zero, embedded image data
- */
- std::vector<uint8_t> mImageData;
-
- /** If image file name is zero, file format of
- * embedded image data.
- */
- std::string mEmbeddedFormat;
-
-};
-
-/** An animation channel. */
-struct AnimationChannel
-{
- /** URL of the data to animate. Could be about anything, but we support only the
- * "NodeID/TransformID.SubElement" notation
- */
- std::string mTarget;
-
- /** Source URL of the time values. Collada calls them "input". Meh. */
- std::string mSourceTimes;
- /** Source URL of the value values. Collada calls them "output". */
- std::string mSourceValues;
-};
-
-/** An animation. Container for 0-x animation channels or 0-x animations */
-struct Animation
-{
- /** Anim name */
- std::string mName;
-
- /** the animation channels, if any */
- std::vector<AnimationChannel> mChannels;
-
- /** the sub-animations, if any */
- std::vector<Animation*> mSubAnims;
-
- /** Destructor */
- ~Animation()
- {
- for ( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
- delete *it;
- }
-};
-
-/** Description of a collada animation channel which has been determined to affect the current node */
-struct ChannelEntry
-{
- const Collada::AnimationChannel* mChannel; ///> the source channel
- 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 mSubElement; // starting index inside the transform data
-
- // resolved data references
- const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
- const Collada::Data* mTimeData; ///> Source data array for the time values
- const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
- const Collada::Data* mValueData; ///> Source datat array for the key value values
-
- ChannelEntry() { mChannel = NULL; mSubElement = 0; }
-};
-
-} // end of namespace Collada
-} // end of namespace Assimp
-
-#endif // AI_COLLADAHELPER_H_INC
diff --git a/3rdparty/assimp/code/ColladaLoader.cpp b/3rdparty/assimp/code/ColladaLoader.cpp
deleted file mode 100644
index c3f0a787..00000000
--- a/3rdparty/assimp/code/ColladaLoader.cpp
+++ /dev/null
@@ -1,1487 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the Collada loader */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_DAE_IMPORTER
-
-#include "../include/aiAnim.h"
-#include "ColladaLoader.h"
-#include "ColladaParser.h"
-
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "SkeletonMeshBuilder.h"
-
-#include "time.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ColladaLoader::ColladaLoader()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-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);
-
- if ( extension == "dae")
- return true;
-
- // XML - too generic, we need to open the file and search for typical keywords
- if ( extension == "xml" || !extension.length() || checkSig) {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"collada"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get file extension list
-void ColladaLoader::GetExtensionList( std::set<std::string>& extensions )
-{
- extensions.insert("dae");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- mFileName = pFile;
-
- // clean all member arrays - just for safety, it should work even if we did not
- mMeshIndexByID.clear();
- mMaterialIndexByName.clear();
- mMeshes.clear();
- newMats.clear();
- mLights.clear();
- mCameras.clear();
- mTextures.clear();
-
- // parse the input file
- ColladaParser parser( pIOHandler, pFile);
-
- 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);
-
- mCameras.reserve(parser.mCameraLibrary.size());
- mLights.reserve(parser.mLightLibrary.size());
-
- // create the materials first, for the meshes to find
- BuildMaterials( parser, pScene);
-
- // build the node hierarchy from it
- pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
-
- // ... then fill the materials with the now adjusted settings
- FillMaterials(parser, pScene);
-
- // 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 all meshes
- StoreSceneMeshes( pScene);
-
- // store all materials
- StoreSceneMaterials( pScene);
-
- // store all lights
- StoreSceneLights( pScene);
-
- // store all cameras
- StoreSceneCameras( pScene);
-
- // store all animations
- StoreAnimations( pScene, parser);
-
-
- // If no meshes have been loaded, it's probably just an animated skeleton.
- if (!pScene->mNumMeshes) {
-
- SkeletonMeshBuilder hero(pScene);
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively constructs a scene node for the given parser node and returns it.
-aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode)
-{
- // create a node for it
- aiNode* node = new aiNode();
-
- // find a name for the new node. It's more complicated than you might think
- node->mName.Set( FindNameForNode( pNode));
-
- // calculate the transformation matrix for it
- node->mTransformation = pParser.CalculateResultTransform( pNode->mTransforms);
-
- // now resolve node instances
- std::vector<const Collada::Node*> instances;
- ResolveNodeInstances(pParser,pNode,instances);
-
- // add children. first the *real* ones
- node->mNumChildren = pNode->mChildren.size()+instances.size();
- node->mChildren = new aiNode*[node->mNumChildren];
-
- 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++)
- {
- node->mChildren[pNode->mChildren.size() + a] = BuildHierarchy( pParser, instances[a]);
- node->mChildren[pNode->mChildren.size() + a]->mParent = node;
- }
-
- // construct meshes
- BuildMeshesForNode( pParser, pNode, node);
-
- // construct cameras
- BuildCamerasForNode(pParser, pNode, node);
-
- // 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)
-{
- // reserve enough storage
- resolved.reserve(pNode->mNodeInstances.size());
-
- // ... and iterate through all nodes to be instanced as children of pNode
- for (std::vector<Collada::NodeInstance>::const_iterator it = pNode->mNodeInstances.begin(),
- end = pNode->mNodeInstances.end(); it != end; ++it)
- {
- // find the corresponding node in the library
- const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find((*it).mNode);
- Collada::Node* nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second;
-
- // 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) {
- nd = const_cast<Collada::Node*>(FindNode(pParser.mRootNode,(*it).mNode));
- }
- if (!nd)
- DefaultLogger::get()->error("Collada: Unable to resolve reference to instanced node " + (*it).mNode);
-
- else {
- // attach this node to the list of children
- resolved.push_back(nd);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Resolve UV channels
-void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
- 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)
- DefaultLogger::get()->error("Collada: Unexpected effect input mapping");
-
- sampler.mUVId = it->second.mSet;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds lights for the given node and references them
-void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
-{
- BOOST_FOREACH( 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())
- {
- DefaultLogger::get()->warn("Collada: Unable to find light for ID \"" + lid.mLight + "\". Skipping.");
- continue;
- }
- const Collada::Light* srcLight = &srcLightIt->second;
- if (srcLight->mType == aiLightSource_AMBIENT) {
- DefaultLogger::get()->error("Collada: Skipping ambient light for the moment");
- continue;
- }
-
- // now fill our ai data structure
- aiLight* out = new aiLight();
- out->mName = pTarget->mName;
- out->mType = (aiLightSourceType)srcLight->mType;
-
- // collada lights point in -Z by default, rest is specified in node transform
- out->mDirection = aiVector3D(0.f,0.f,-1.f);
-
- out->mAttenuationConstant = srcLight->mAttConstant;
- out->mAttenuationLinear = srcLight->mAttLinear;
- out->mAttenuationQuadratic = srcLight->mAttQuadratic;
-
- // collada doesn't differenciate between these color types
- out->mColorDiffuse = out->mColorSpecular = out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
-
- // 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. FUCKING COLLADA.
- if (srcLight->mOuterAngle == 10e10f)
- {
- // ... some deprecation magic. FUCKING FCOLLADA.
- if (srcLight->mPenumbraAngle == 10e10f)
- {
- // 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 = AI_DEG_TO_RAD (acos(pow(0.1f,1.f/srcLight->mFalloffExponent))+
- srcLight->mFalloffAngle);
- }
- 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 );
- }
-
- // add to light list
- mLights.push_back(out);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds cameras for the given node and references them
-void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
-{
- BOOST_FOREACH( 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())
- {
- DefaultLogger::get()->warn("Collada: Unable to find camera for ID \"" + cid.mCamera + "\". Skipping.");
- continue;
- }
- const Collada::Camera* srcCamera = &srcCameraIt->second;
-
- // orthographic cameras not yet supported in Assimp
- if (srcCamera->mOrtho) {
- DefaultLogger::get()->warn("Collada: Orthographic cameras are not supported.");
- }
-
- // now fill our ai data structure
- aiCamera* out = new aiCamera();
- out->mName = pTarget->mName;
-
- // collada cameras point in -Z by default, rest is specified in node transform
- out->mLookAt = aiVector3D(0.f,0.f,-1.f);
-
- // near/far z is already ok
- out->mClipPlaneFar = srcCamera->mZFar;
- out->mClipPlaneNear = srcCamera->mZNear;
-
- // ... but for the rest some values are optional
- // and we need to compute the others in any combination. FUCKING COLLADA.
- if (srcCamera->mAspect != 10e10f)
- out->mAspect = srcCamera->mAspect;
-
- if (srcCamera->mHorFov != 10e10f) {
- out->mHorizontalFOV = srcCamera->mHorFov;
-
- if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
- out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
- tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
- }
- }
- else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
- out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect *
- tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
- }
-
- // Collada uses degrees, we use radians
- out->mHorizontalFOV = AI_DEG_TO_RAD(out->mHorizontalFOV);
-
- // add to camera list
- mCameras.push_back(out);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds meshes for the given node and references them
-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
- BOOST_FOREACH( const Collada::MeshInstance& mid, pNode->mMeshes)
- {
- const Collada::Mesh* srcMesh = NULL;
- const Collada::Controller* srcController = NULL;
-
- // find the referred mesh
- ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid.mMeshOrController);
- 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())
- {
- srcController = &srcContrIt->second;
- srcMeshIt = pParser.mMeshLibrary.find( srcController->mMeshId);
- if ( srcMeshIt != pParser.mMeshLibrary.end())
- srcMesh = srcMeshIt->second;
- }
-
- if ( !srcMesh)
- {
- DefaultLogger::get()->warn( boost::str( boost::format( "Collada: Unable to find geometry for ID \"%s\". Skipping.") % mid.mMeshOrController));
- continue;
- }
- } 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)
- {
- const Collada::SubMesh& submesh = srcMesh->mSubMeshes[sm];
- if ( submesh.mNumFaces == 0)
- continue;
-
- // find material assigned to this submesh
- std::map<std::string, Collada::SemanticMappingTable >::const_iterator meshMatIt = mid.mMaterials.find( submesh.mMaterial);
-
- const Collada::SemanticMappingTable* table;
- if ( meshMatIt != mid.mMaterials.end())
- table = &meshMatIt->second;
- else {
- table = NULL;
- DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup \"%s\" in geometry \"%s\".") % submesh.mMaterial % mid.mMeshOrController));
- }
- const std::string& meshMaterial = table ? table->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())
- matIdx = matIt->second;
- else
- matIdx = 0;
-
- if (table && !table->mMap.empty() ) {
- std::pair<Collada::Effect*, aiMaterial*>& mat = newMats[matIdx];
-
- // Iterate through all texture channels assigned to the effect and
- // check whether we have mapping information for it.
- ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent,*table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
- }
-
- // built lookup index of the Mesh-Submesh-Material combination
- ColladaMeshIndex index( mid.mMeshOrController, sm, meshMaterial);
-
- // if we already have the mesh at the library, just add its index to the node's array
- std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find( index);
- if ( dstMeshIt != mMeshIndexByID.end()) {
- newMeshRefs.push_back( dstMeshIt->second);
- }
- 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);
-
- // store the mesh, and store its new index in the node
- newMeshRefs.push_back( mMeshes.size());
- mMeshIndexByID[index] = mMeshes.size();
- mMeshes.push_back( dstMesh);
- vertexStart += dstMesh->mNumVertices; faceStart += submesh.mNumFaces;
-
- // assign the material index
- dstMesh->mMaterialIndex = matIdx;
- }
- }
- }
-
- // now place all mesh references we gathered in the target node
- pTarget->mNumMeshes = newMeshRefs.size();
- if ( newMeshRefs.size())
- {
- pTarget->mMeshes = new unsigned int[pTarget->mNumMeshes];
- std::copy( newMeshRefs.begin(), newMeshRefs.end(), pTarget->mMeshes);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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;
-
- // count the vertices addressed by its faces
- const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
- pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, 0);
-
- // copy positions
- dstMesh->mNumVertices = numVertices;
- dstMesh->mVertices = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
- pStartVertex + numVertices, dstMesh->mVertices);
-
- // normals, if given. HACK: (thom) Due to the fucking 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)
- {
- 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)
- {
- 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)
- {
- dstMesh->mBitangents = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() +
- pStartVertex + numVertices, dstMesh->mBitangents);
- }
-
- // 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)
- {
- dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
- for ( size_t b = 0; b < numVertices; ++b)
- dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
-
- dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
- ++real;
- }
- }
-
- // 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)
- {
- dstMesh->mColors[real] = new aiColor4D[numVertices];
- std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
- ++real;
- }
- }
-
- // create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
- size_t vertex = 0;
- dstMesh->mNumFaces = pSubMesh.mNumFaces;
- dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
- for ( size_t a = 0; a < dstMesh->mNumFaces; ++a)
- {
- size_t s = pSrcMesh->mFaceSize[ pStartFace + a];
- aiFace& face = dstMesh->mFaces[a];
- face.mNumIndices = s;
- face.mIndices = new unsigned int[s];
- for ( size_t b = 0; b < s; ++b)
- face.mIndices[b] = vertex++;
- }
-
- // create bones if given
- if ( pSrcController)
- {
- // refuse if the vertex count does not match
-// if ( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
-// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
-
- // resolve references - joint names
- const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
- const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
- // joint offset matrices
- const Collada::Accessor& jointMatrixAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointOffsetMatrixSource);
- const Collada::Data& jointMatrices = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointMatrixAcc.mSource);
- // joint vertex_weight name list - should refer to the same list as the joint names above. If not, report and reconsider
- const Collada::Accessor& weightNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputJoints.mAccessor);
- if ( &weightNamesAcc != &jointNamesAcc)
- throw DeadlyImportError( "Temporary implementational lazyness. If you read this, please report to the author.");
- // vertex weights
- const Collada::Accessor& weightsAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputWeights.mAccessor);
- const Collada::Data& weights = pParser.ResolveLibraryReference( pParser.mDataLibrary, weightsAcc.mSource);
-
- if ( !jointNames.mIsStringArray || jointMatrices.mIsStringArray || weights.mIsStringArray)
- throw DeadlyImportError( "Data type mismatch while resolving mesh joints");
- // sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex
- if ( pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1)
- throw DeadlyImportError( "Unsupported vertex_weight adresssing scheme. Fucking collada spec.");
-
- // create containers to collect the weights for each bone
- size_t numBones = jointNames.mStrings.size();
- std::vector<std::vector<aiVertexWeight> > dstBones( numBones);
-
- // build a temporary array of pointers to the start of each vertex's weights
- typedef std::vector< std::pair<size_t, size_t> > IndexPairVector;
- std::vector<IndexPairVector::const_iterator> weightStartPerVertex( pSrcController->mWeightCounts.size());
- IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
- 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)
- {
- // 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];
- // find the vertex weights for this vertex
- 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;
-
- float weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
-
- // one day I gonna kill that XSI Collada exporter
- if ( weight > 0.0f)
- {
- aiVertexWeight w;
- w.mVertexId = a - pStartVertex;
- w.mWeight = weight;
- dstBones[jointIndex].push_back( w);
- }
- }
- }
-
- // 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++;
-
- // create bone array and copy bone weights one by one
- dstMesh->mNumBones = numRemainingBones;
- dstMesh->mBones = new aiBone*[numRemainingBones];
- size_t boneCount = 0;
- for ( size_t a = 0; a < numBones; ++a)
- {
- // omit bones without weights
- if ( dstBones[a].size() == 0)
- continue;
-
- // create bone with its weights
- aiBone* bone = new aiBone;
- bone->mName = ReadString( jointNamesAcc, jointNames, a);
- bone->mOffsetMatrix.a1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 0);
- bone->mOffsetMatrix.a2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 1);
- bone->mOffsetMatrix.a3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 2);
- bone->mOffsetMatrix.a4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 3);
- bone->mOffsetMatrix.b1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 4);
- bone->mOffsetMatrix.b2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 5);
- bone->mOffsetMatrix.b3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 6);
- bone->mOffsetMatrix.b4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 7);
- bone->mOffsetMatrix.c1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 8);
- bone->mOffsetMatrix.c2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 9);
- bone->mOffsetMatrix.c3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 10);
- bone->mOffsetMatrix.c4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 11);
- bone->mNumWeights = dstBones[a].size();
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- std::copy( dstBones[a].begin(), dstBones[a].end(), bone->mWeights);
-
- // apply bind shape matrix to offset matrix
- aiMatrix4x4 bindShapeMatrix;
- bindShapeMatrix.a1 = pSrcController->mBindShapeMatrix[0];
- bindShapeMatrix.a2 = pSrcController->mBindShapeMatrix[1];
- bindShapeMatrix.a3 = pSrcController->mBindShapeMatrix[2];
- bindShapeMatrix.a4 = pSrcController->mBindShapeMatrix[3];
- bindShapeMatrix.b1 = pSrcController->mBindShapeMatrix[4];
- bindShapeMatrix.b2 = pSrcController->mBindShapeMatrix[5];
- bindShapeMatrix.b3 = pSrcController->mBindShapeMatrix[6];
- bindShapeMatrix.b4 = pSrcController->mBindShapeMatrix[7];
- bindShapeMatrix.c1 = pSrcController->mBindShapeMatrix[8];
- bindShapeMatrix.c2 = pSrcController->mBindShapeMatrix[9];
- bindShapeMatrix.c3 = pSrcController->mBindShapeMatrix[10];
- bindShapeMatrix.c4 = pSrcController->mBindShapeMatrix[11];
- bindShapeMatrix.d1 = pSrcController->mBindShapeMatrix[12];
- bindShapeMatrix.d2 = pSrcController->mBindShapeMatrix[13];
- bindShapeMatrix.d3 = pSrcController->mBindShapeMatrix[14];
- bindShapeMatrix.d4 = pSrcController->mBindShapeMatrix[15];
- bone->mOffsetMatrix *= bindShapeMatrix;
-
- // HACK: (thom) Some exporters address the bone nodes by SID, others address them by ID or even name.
- // Therefore I added a little name replacement here: I search for the bone's node by either name, ID or SID,
- // 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)
- bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data);
-
- // assign the name that we would have assigned for the source node
- if ( bnode)
- bone->mName.Set( FindNameForNode( bnode));
- else
- DefaultLogger::get()->warn( boost::str( boost::format( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"%s\".") % bone->mName.data));
-
- // and insert bone
- dstMesh->mBones[boneCount++] = bone;
- }
- }
-
- return dstMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all meshes in the given scene
-void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
-{
- pScene->mNumMeshes = mMeshes.size();
- if ( mMeshes.size() > 0)
- {
- 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)
-{
- pScene->mNumCameras = mCameras.size();
- if ( mCameras.size() > 0)
- {
- 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)
-{
- pScene->mNumLights = mLights.size();
- if ( mLights.size() > 0)
- {
- 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)
-{
- pScene->mNumTextures = mTextures.size();
- if ( mTextures.size() > 0)
- {
- 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)
-{
- pScene->mNumMaterials = 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();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all animations
-void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
-{
- // recursivly 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)
- {
- aiAnimation* templateAnim = mAnims[a];
- 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)
- {
- aiAnimation* other = mAnims[b];
- if ( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
- collectedAnimIndices.push_back( b);
- }
-
- // if there are other animations which fit the template anim, combine all channels into a single anim
- if ( !collectedAnimIndices.empty() )
- {
- aiAnimation* combinedAnim = new aiAnimation();
- combinedAnim->mName = aiString( std::string( "combinedAnim_") + char( '0' + a));
- combinedAnim->mDuration = templateAnim->mDuration;
- combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
- combinedAnim->mNumChannels = collectedAnimIndices.size() + 1;
- combinedAnim->mChannels = new aiNodeAnim*[combinedAnim->mNumChannels];
- // add the template anim as first channel by moving its aiNodeAnim to the combined animation
- combinedAnim->mChannels[0] = templateAnim->mChannels[0];
- templateAnim->mChannels[0] = NULL;
- delete templateAnim;
- // combined animation replaces template animation in the anim array
- mAnims[a] = combinedAnim;
-
- // move the memory of all other anims to the combined anim and erase them from the source anims
- for ( size_t b = 0; b < collectedAnimIndices.size(); ++b)
- {
- aiAnimation* srcAnimation = mAnims[collectedAnimIndices[b]];
- combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0];
- srcAnimation->mChannels[0] = NULL;
- delete srcAnimation;
- }
-
- // in a second go, delete all the single-channel-anims that we've stripped from their channels
- // back to front to preserve indices - you know, removing an element from a vector moves all elements behind the removed one
- while ( !collectedAnimIndices.empty() )
- {
- mAnims.erase( mAnims.begin() + collectedAnimIndices.back());
- collectedAnimIndices.pop_back();
- }
- }
- }
- }
-
- // now store all anims in the scene
- if ( !mAnims.empty())
- {
- pScene->mNumAnimations = mAnims.size();
- pScene->mAnimations = new aiAnimation*[mAnims.size()];
- std::copy( mAnims.begin(), mAnims.end(), pScene->mAnimations);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the animations for the given source anim
-void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string pPrefix)
-{
- std::string animName = pPrefix.empty() ? pSrcAnim->mName : pPrefix + "_" + pSrcAnim->mName;
-
- // create nested animations, if given
- for ( std::vector<Collada::Animation*>::const_iterator it = pSrcAnim->mSubAnims.begin(); it != pSrcAnim->mSubAnims.end(); ++it)
- StoreAnimations( pScene, pParser, *it, animName);
-
- // create animation channels, if any
- if ( !pSrcAnim->mChannels.empty())
- CreateAnimation( pScene, pParser, pSrcAnim, animName);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the animation for the given source anim
-void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName)
-{
- // collect a list of animatable nodes
- std::vector<const aiNode*> nodes;
- CollectNodes( pScene->mRootNode, nodes);
-
- std::vector<aiNodeAnim*> anims;
- for ( std::vector<const aiNode*>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit)
- {
- // find all the collada anim channels which refer to the current node
- std::vector<Collada::ChannelEntry> entries;
- std::string nodeName = (*nit)->mName.data;
-
- // find the collada node corresponding to the aiNode
- const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
-// ai_assert( srcNode != NULL);
- if ( !srcNode)
- continue;
-
- // now check all channels if they affect the current node
- for ( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
- cit != pSrcAnim->mChannels.end(); ++cit)
- {
- const Collada::AnimationChannel& srcChannel = *cit;
- Collada::ChannelEntry entry;
-
- // we except the animation target to be of type "nodeName/transformID.subElement". Ignore all others
- // find the slash that separates the node name - there should be only one
- std::string::size_type slashPos = srcChannel.mTarget.find( '/');
- if ( slashPos == std::string::npos)
- continue;
- if ( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos)
- continue;
- std::string targetID = srcChannel.mTarget.substr( 0, slashPos);
- if ( targetID != srcNode->mID)
- continue;
-
- // find the dot that separates the transformID - there should be only one or zero
- std::string::size_type dotPos = srcChannel.mTarget.find( '.');
- if ( dotPos != std::string::npos)
- {
- if ( srcChannel.mTarget.find( '.', dotPos+1) != std::string::npos)
- continue;
-
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
-
- std::string subElement = srcChannel.mTarget.substr( dotPos+1);
- if ( subElement == "ANGLE")
- entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
- else if ( subElement == "X")
- entry.mSubElement = 0;
- else if ( subElement == "Y")
- entry.mSubElement = 1;
- else if ( subElement == "Z")
- entry.mSubElement = 2;
- else
- DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement \"%s\". Ignoring") % subElement));
- } else
- {
- // no subelement following, transformId is remaining string
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
- }
-
- // determine which transform step is affected by this channel
- entry.mTransformIndex = 0xffffffff;
- for ( size_t a = 0; a < srcNode->mTransforms.size(); ++a)
- if ( srcNode->mTransforms[a].mID == entry.mTransformId)
- entry.mTransformIndex = a;
-
- if ( entry.mTransformIndex == 0xffffffff)
- continue;
-
- entry.mChannel = &(*cit);
- entries.push_back( entry);
- }
-
- // if there's no channel affecting the current node, we skip it
- if ( entries.empty())
- continue;
-
- // resolve the data pointers for all anim channels. Find the minimum time while we're at it
- float startTime = 1e20f, endTime = -1e20f;
- for ( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
- e.mTimeAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
- e.mTimeData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mTimeAccessor->mSource);
- e.mValueAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceValues);
- e.mValueData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mValueAccessor->mSource);
-
- // time count and value count must match
- if ( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
- throw DeadlyImportError( boost::str( boost::format( "Time count / value count mismatch in animation channel \"%s\".") % e.mChannel->mTarget));
-
- // find bounding times
- startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0));
- endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
- }
-
- // create a local transformation chain of the node's transforms
- std::vector<Collada::Transform> transforms = srcNode->mTransforms;
-
- // now for every unique point in time, find or interpolate the key values for that time
- // and apply them to the transform chain. Then the node's present transformation can be calculated.
- float time = startTime;
- std::vector<aiMatrix4x4> resultTrafos;
- while ( 1)
- {
- for ( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
-
- // find the keyframe behind the current point in time
- size_t pos = 0;
- float postTime = 0.f;
- while ( 1)
- {
- if ( pos >= e.mTimeAccessor->mCount)
- break;
- postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
- if ( postTime >= time)
- break;
- ++pos;
- }
-
- pos = std::min( pos, e.mTimeAccessor->mCount-1);
-
- // read values from there
- float temp[16];
- for ( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
-
- // if not exactly at the key time, interpolate with previous value set
- if ( postTime > time && pos > 0)
- {
- float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
- float factor = (time - postTime) / (preTime - postTime);
-
- for ( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- {
- float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
- temp[c] += (v - temp[c]) * factor;
- }
- }
-
- // Apply values to current transformation
- std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
- }
-
- // Calculate resulting transformation
- aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
-
- // out of lazyness: we store the time in matrix.d4
- mat.d4 = time;
- resultTrafos.push_back( mat);
-
- // find next point in time to evaluate. That's the closest frame larger than the current in any channel
- float nextTime = 1e20f;
- for ( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
-
- // find the next time value larger than the current
- size_t pos = 0;
- while ( pos < e.mTimeAccessor->mCount)
- {
- float t = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
- if ( t > time)
- {
- nextTime = std::min( nextTime, t);
- break;
- }
- ++pos;
- }
- }
-
- // no more keys on any channel after the current time -> we're done
- if ( nextTime > 1e19)
- break;
-
- // else construct next keyframe at this following time point
- time = nextTime;
- }
-
- // there should be some keyframes
- ai_assert( resultTrafos.size() > 0);
-
- // build an animation channel for the given node out of these trafo keys
- aiNodeAnim* dstAnim = new aiNodeAnim;
- dstAnim->mNodeName = nodeName;
- dstAnim->mNumPositionKeys = resultTrafos.size();
- dstAnim->mNumRotationKeys= resultTrafos.size();
- dstAnim->mNumScalingKeys = resultTrafos.size();
- dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
- dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
- dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
-
- for ( size_t a = 0; a < resultTrafos.size(); ++a)
- {
- const aiMatrix4x4& mat = resultTrafos[a];
- double time = double( mat.d4); // remember? time is stored in mat.d4
-
- dstAnim->mPositionKeys[a].mTime = time;
- dstAnim->mRotationKeys[a].mTime = time;
- dstAnim->mScalingKeys[a].mTime = time;
- mat.Decompose( dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
- }
-
- anims.push_back( dstAnim);
- }
-
- if ( !anims.empty())
- {
- aiAnimation* anim = new aiAnimation;
- anim->mName.Set( pName);
- anim->mNumChannels = anims.size();
- anim->mChannels = new aiNodeAnim*[anims.size()];
- std::copy( anims.begin(), anims.end(), anim->mChannels);
- anim->mDuration = 0.0f;
- for ( size_t a = 0; a < anims.size(); ++a)
- {
- anim->mDuration = std::max( anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys-1].mTime);
- }
- anim->mTicksPerSecond = 1;
- mAnims.push_back( anim);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a texture to a material structure
-void ColladaLoader::AddTexture ( Assimp::MaterialHelper& mat, const ColladaParser& pParser,
- const Collada::Effect& effect,
- const Collada::Sampler& sampler,
- aiTextureType type, unsigned int idx)
-{
- // first of all, basic file name
- const aiString name = FindFilenameForEffectTexture( pParser, effect, sampler.mName );
- mat.AddProperty( &name, _AI_MATKEY_TEXTURE_BASE, type, idx );
-
- // mapping mode
- int map = aiTextureMapMode_Clamp;
- if (sampler.mWrapU)
- map = aiTextureMapMode_Wrap;
- if (sampler.mWrapU && sampler.mMirrorU)
- map = aiTextureMapMode_Mirror;
-
- mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_U_BASE, type, idx);
-
- map = aiTextureMapMode_Clamp;
- if (sampler.mWrapV)
- map = aiTextureMapMode_Wrap;
- if (sampler.mWrapV && sampler.mMirrorV)
- map = aiTextureMapMode_Mirror;
-
- mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_V_BASE, type, idx);
-
- // UV transformation
- mat.AddProperty(&sampler.mTransform, 1,
- _AI_MATKEY_UVTRANSFORM_BASE, type, idx);
-
- // Blend mode
- mat.AddProperty((int*)&sampler.mOp , 1,
- _AI_MATKEY_TEXBLEND_BASE, type, idx);
-
- // Blend factor
- mat.AddProperty((float*)&sampler.mWeighting , 1,
- _AI_MATKEY_TEXBLEND_BASE, type, idx);
-
- // UV source index ... if we didn't resolve the mapping it is actually just
- // a guess but it works in most cases. We search for the frst occurence of a
- // number in the channel name. We assume it is the zero-based index into the
- // UV channel array of all corresponding meshes. It could also be one-based
- // for some exporters, but we won't care of it unless someone complains about.
- if (sampler.mUVId != 0xffffffff)
- map = sampler.mUVId;
- else {
- map = -1;
- for (std::string::const_iterator it = sampler.mUVChannel.begin();it != sampler.mUVChannel.end(); ++it){
- if (IsNumeric(*it)) {
- map = strtol10(&(*it));
- break;
- }
- }
- if (-1 == map) {
- DefaultLogger::get()->warn("Collada: unable to determine UV channel for texture");
- map = 0;
- }
- }
- mat.AddProperty(&map,1,_AI_MATKEY_UVWSRC_BASE,type,idx);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Fills materials from the collada material definitions
-void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pScene*/)
-{
- for (std::vector<std::pair<Collada::Effect*, aiMaterial*> >::iterator it = newMats.begin(),
- end = newMats.end(); it != end; ++it)
- {
- MaterialHelper& mat = (MaterialHelper&)*it->second;
- Collada::Effect& effect = *it->first;
-
- // resolve shading mode
- int shadeMode;
- if (effect.mFaceted) /* fixme */
- shadeMode = aiShadingMode_Flat;
- else {
- switch( effect.mShadeType)
- {
- case Collada::Shade_Constant:
- shadeMode = aiShadingMode_NoShading;
- break;
- case Collada::Shade_Lambert:
- shadeMode = aiShadingMode_Gouraud;
- break;
- case Collada::Shade_Blinn:
- shadeMode = aiShadingMode_Blinn;
- break;
- case Collada::Shade_Phong:
- shadeMode = aiShadingMode_Phong;
- break;
-
- default:
- DefaultLogger::get()->warn("Collada: Unrecognized shading mode, using gouraud shading");
- shadeMode = aiShadingMode_Gouraud;
- break;
- }
- }
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // double-sided?
- shadeMode = effect.mDoubleSided;
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_TWOSIDED);
-
- // wireframe?
- shadeMode = effect.mWireframe;
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_ENABLE_WIREFRAME);
-
- // add material colors
- mat.AddProperty( &effect.mAmbient, 1,AI_MATKEY_COLOR_AMBIENT);
- mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR);
- mat.AddProperty( &effect.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
- mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
- mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE);
-
- // scalar properties
- mat.AddProperty( &effect.mShininess, 1, AI_MATKEY_SHININESS);
- mat.AddProperty( &effect.mReflectivity, 1, AI_MATKEY_REFLECTIVITY);
- mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
-
- // transparency, a very hard one. seemingly not all files are following the
- // specification here .. but we can trick.
- if (effect.mTransparency > 0.f && effect.mTransparency < 1.f) {
- effect.mTransparency = 1.f- effect.mTransparency;
- mat.AddProperty( &effect.mTransparency, 1, AI_MATKEY_OPACITY );
- mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
- }
-
- // add textures, if given
- if ( !effect.mTexAmbient.mName.empty())
- /* It is merely a lightmap */
- AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
-
- if ( !effect.mTexEmissive.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
-
- if ( !effect.mTexSpecular.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexSpecular, aiTextureType_SPECULAR);
-
- if ( !effect.mTexDiffuse.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexDiffuse, aiTextureType_DIFFUSE);
-
- if ( !effect.mTexBump.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexBump, aiTextureType_HEIGHT);
-
- if ( !effect.mTexTransparent.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexTransparent, aiTextureType_OPACITY);
-
- if ( !effect.mTexReflective.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexReflective, aiTextureType_REFLECTION);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs materials from the collada material definitions
-void ColladaLoader::BuildMaterials( const ColladaParser& pParser, aiScene* /*pScene*/)
-{
- newMats.reserve(pParser.mMaterialLibrary.size());
-
- for ( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt)
- {
- const Collada::Material& material = matIt->second;
- // a material is only a reference to an effect
- ColladaParser::EffectLibrary::const_iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
- if ( effIt == pParser.mEffectLibrary.end())
- continue;
- const Collada::Effect& effect = effIt->second;
-
- // create material
- Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
- aiString name( matIt->first);
- mat->AddProperty(&name,AI_MATKEY_NAME);
-
- // MEGA SUPER MONSTER HACK by Alex ... It's all my fault, yes.
- // We store the reference to the effect in the material and
- // return ... we'll add the actual material properties later
- // after we processed all meshes. During mesh processing,
- // we evaluate vertex input mappings. Afterwards we should be
- // able to correctly setup source UV channels for textures.
-
- // ... moved to ColladaLoader::FillMaterials()
- // *duck*
-
- // store the material
- mMaterialIndexByName[matIt->first] = newMats.size();
- newMats.push_back( std::pair<Collada::Effect*, aiMaterial*>(const_cast<Collada::Effect*>(&effect),mat) );
- }
- // ScenePreprocessor generates a default material automatically if none is there.
- // All further code here in this loader works well without a valid material so
- // we can safely let it to ScenePreprocessor.
-#if 0
- if ( newMats.size() == 0)
- {
- Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
- aiString name( AI_DEFAULT_MATERIAL_NAME );
- mat->AddProperty( &name, AI_MATKEY_NAME);
-
- const int shadeMode = aiShadingMode_Phong;
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- aiColor4D colAmbient( 0.2f, 0.2f, 0.2f, 1.0f), colDiffuse( 0.8f, 0.8f, 0.8f, 1.0f), colSpecular( 0.5f, 0.5f, 0.5f, 0.5f);
- mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- const float specExp = 5.0f;
- mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
- }
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// Resolves the texture name for the given effect texture entry
-aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
- const Collada::Effect& pEffect, const std::string& pName)
-{
- // recurse through the param references until we end up at an image
- std::string name = pName;
- while ( 1)
- {
- // the given string is a param entry. Find it
- Collada::Effect::ParamLibrary::const_iterator it = pEffect.mParams.find( name);
- // if not found, we're at the end of the recursion. The resulting string should be the image ID
- if ( it == pEffect.mParams.end())
- break;
-
- // else recurse on
- name = it->second.mReference;
- }
-
- // find the image referred by this name in the image library of the scene
- ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
- if ( imIt == pParser.mImageLibrary.end())
- {
- throw DeadlyImportError( boost::str( boost::format(
- "Collada: Unable to resolve effect texture entry \"%s\", ended up at ID \"%s\".") % pName % name));
- }
-
- aiString result;
-
- // if this is an embedded texture image setup an aiTexture for it
- if (imIt->second.mFileName.empty())
- {
- if (imIt->second.mImageData.empty()) {
- throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
- }
-
- aiTexture* tex = new aiTexture();
-
- // setup format hint
- if (imIt->second.mEmbeddedFormat.length() > 3) {
- DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters");
- }
- strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3);
-
- // and copy texture data
- tex->mHeight = 0;
- tex->mWidth = imIt->second.mImageData.size();
- tex->pcData = (aiTexel*)new char[tex->mWidth];
- memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
-
- // setup texture reference string
- result.data[0] = '*';
- result.length = 1 + ASSIMP_itoa10(result.data+1,MAXLEN-1,mTextures.size());
-
- // and add this texture to the list
- mTextures.push_back(tex);
- }
- else
- {
- result.Set( imIt->second.mFileName );
- ConvertPath(result);
- }
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a path read from a collada file to the usual representation
-void ColladaLoader::ConvertPath (aiString& ss)
-{
- // TODO: collada spec, p 22. Handle URI correctly.
- // For the moment we're just stripping the file:// away to make it work.
- // Windoes doesn't seem to be able to find stuff like
- // 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
- if (0 == strncmp(ss.data,"file://",7))
- {
- ss.length -= 7;
- memmove(ss.data,ss.data+7,ss.length);
- ss.data[ss.length] = '\0';
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a float value from an accessor and its data array.
-float ColladaLoader::ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
-{
- // FIXME: (thom) Test for data type here in every access? For the moment, I leave this to the caller
- size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
- ai_assert( pos < pData.mValues.size());
- return pData.mValues[pos];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a string value from an accessor and its data array.
-const std::string& ColladaLoader::ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const
-{
- size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset;
- ai_assert( pos < pData.mStrings.size());
- return pData.mStrings[pos];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collects all nodes into the given array
-void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const
-{
- poNodes.push_back( pNode);
-
- for ( size_t a = 0; a < pNode->mNumChildren; ++a)
- CollectNodes( pNode->mChildren[a], poNodes);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds a node in the collada scene by the given name
-const Collada::Node* ColladaLoader::FindNode( const Collada::Node* pNode, const std::string& pName) const
-{
- if ( pNode->mName == pName || pNode->mID == pName)
- return pNode;
-
- for ( size_t a = 0; a < pNode->mChildren.size(); ++a)
- {
- const Collada::Node* node = FindNode( pNode->mChildren[a], pName);
- if ( node)
- return node;
- }
-
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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;
-
- 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;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds a proper name for a node derived from the collada-node's properties
-std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode) const
-{
- // now setup the name of the node. We take the name if not empty, otherwise the collada ID
- // FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default.
- if (!pNode->mName.empty() && pNode->mName != "untitled")
- return pNode->mName;
- else if (!pNode->mID.empty())
- return pNode->mID;
- else if (!pNode->mSID.empty())
- return pNode->mSID;
- else
- {
- // No need to worry. Unnamed nodes are no problem at all, except
- // if cameras or lights need to be assigned to them.
- return boost::str( boost::format( "$ColladaAutoName$_%d") % clock());
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
diff --git a/3rdparty/assimp/code/ColladaLoader.h b/3rdparty/assimp/code/ColladaLoader.h
deleted file mode 100644
index 1fcdff1e..00000000
--- a/3rdparty/assimp/code/ColladaLoader.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/** Defines the collada loader class */
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef AI_COLLADALOADER_H_INC
-#define AI_COLLADALOADER_H_INC
-
-#include "BaseImporter.h"
-#include "ColladaParser.h"
-
-namespace Assimp
-{
-
-struct ColladaMeshIndex
-{
- std::string mMeshID;
- size_t mSubMesh;
- std::string mMaterial;
- ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
- : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
- { }
-
- bool operator < (const ColladaMeshIndex& p) const
- {
- if ( mMeshID == p.mMeshID)
- {
- if ( mSubMesh == p.mSubMesh)
- return mMaterial < p.mMaterial;
- else
- return mSubMesh < p.mSubMesh;
- } else
- {
- return mMeshID < p.mMeshID;
- }
- }
-};
-
-/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
- * more useless stuff, so I limited the data to what I think is useful for games.
-*/
-class ColladaLoader : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- ColladaLoader();
-
- /** Destructor, private as well */
- ~ColladaLoader();
-
-public:
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-protected:
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList( std::set<std::string>& extensions);
-
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- /** Recursively constructs a scene node for the given parser node and returns it. */
- aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
-
- /** Resolve node instances */
- void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
- std::vector<const Collada::Node*>& resolved);
-
- /** Builds meshes for the given node and references them */
- void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
- aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
- const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
-
- /** Builds cameras for the given node and references them */
- void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- /** Builds lights for the given node and references them */
- void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- /** Stores all meshes in the given scene */
- void StoreSceneMeshes( aiScene* pScene);
-
- /** Stores all materials in the given scene */
- void StoreSceneMaterials( aiScene* pScene);
-
- /** Stores all lights in the given scene */
- void StoreSceneLights( aiScene* pScene);
-
- /** Stores all cameras in the given scene */
- void StoreSceneCameras( aiScene* pScene);
-
- /** Stores all textures in the given scene */
- void StoreSceneTextures( aiScene* pScene);
-
- /** Stores all animations
- * @param pScene target scene to store the anims
- */
- void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
-
- /** Stores all animations for the given source anim and its nested child animations
- * @param pScene target scene to store the anims
- * @param pSrcAnim the source animation to process
- * @param pPrefix Prefix to the name in case of nested animations
- */
- void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string pPrefix);
-
- /** Constructs the animation for the given source anim */
- void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
-
- /** Constructs materials from the collada material definitions */
- void BuildMaterials( const ColladaParser& pParser, aiScene* pScene);
-
- /** Fill materials from the collada material definitions */
- void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
-
- /** Resolve UV channel mappings*/
- void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
- const Collada::SemanticMappingTable& table);
-
- /** Add a texture and all of its sampling properties to a material*/
- void AddTexture ( Assimp::MaterialHelper& mat, const ColladaParser& pParser,
- const Collada::Effect& effect,
- const Collada::Sampler& sampler,
- aiTextureType type, unsigned int idx = 0);
-
- /** Resolves the texture name for the given effect texture entry */
- aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
- const Collada::Effect& pEffect, const std::string& pName);
-
- /** Converts a path read from a collada file to the usual representation */
- void ConvertPath( aiString& ss);
-
- /** Reads a float value from an accessor and its data array.
- * @param pAccessor The accessor to use for reading
- * @param pData The data array to read from
- * @param pIndex The index of the element to retrieve
- * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
- * @return the specified value
- */
- float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
-
- /** Reads a string value from an accessor and its data array.
- * @param pAccessor The accessor to use for reading
- * @param pData The data array to read from
- * @param pIndex The index of the element to retrieve
- * @return the specified value
- */
- const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
-
- /** Recursively collects all nodes into the given array */
- void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
-
- /** Finds a node in the collada scene by the given name */
- const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
- /** Finds a node in the collada scene by the given SID */
- const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
-
- /** Finds a proper name for a node derived from the collada-node's properties */
- std::string FindNameForNode( const Collada::Node* pNode) const;
-
-protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** Which mesh-material compound was stored under which mesh ID */
- std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
-
- /** Which material was stored under which index in the scene */
- std::map<std::string, size_t> mMaterialIndexByName;
-
- /** Accumulated meshes for the target scene */
- std::vector<aiMesh*> mMeshes;
-
- /** Temporary material list */
- std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
-
- /** Temporary camera list */
- std::vector<aiCamera*> mCameras;
-
- /** Temporary light list */
- std::vector<aiLight*> mLights;
-
- /** Temporary texture list */
- std::vector<aiTexture*> mTextures;
-
- /** Accumulated animations for the target scene */
- std::vector<aiAnimation*> mAnims;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_COLLADALOADER_H_INC
diff --git a/3rdparty/assimp/code/ColladaParser.cpp b/3rdparty/assimp/code/ColladaParser.cpp
deleted file mode 100644
index e2dfffbc..00000000
--- a/3rdparty/assimp/code/ColladaParser.cpp
+++ /dev/null
@@ -1,2796 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file ColladaParser.cpp
- * @brief Implementation of the Collada parser helper
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_DAE_IMPORTER
-
-#include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-
-using namespace Assimp;
-using namespace Assimp::Collada;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
- : mFileName( pFile)
-{
- mRootNode = NULL;
- mUnitSize = 1.0f;
- mUpDirection = UP_Z;
-
- // We assume the newest file format by default
- mFormat = FV_1_5_n;
-
- // open the file
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- // generate a XML reader for it
- boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- if ( !mReader)
- ThrowException( "Collada: Unable to open file.");
-
- // start reading
- ReadContents();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ColladaParser::~ColladaParser()
-{
- delete mReader;
- for ( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
- delete it->second;
- for ( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
- delete it->second;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read bool from text contents of current element
-bool ColladaParser::ReadBoolFromTextContent()
-{
- const char* cur = GetTextContent();
- return (!ASSIMP_strincmp(cur,"true",4) || '0' != *cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read float from text contents of current element
-float ColladaParser::ReadFloatFromTextContent()
-{
- const char* cur = GetTextContent();
- return fast_atof(cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the contents of the file
-void ColladaParser::ReadContents()
-{
- while ( mReader->read())
- {
- // handle the root element "COLLADA"
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "COLLADA"))
- {
- // check for 'version' attribute
- const int attrib = TestAttribute("version");
- if (attrib != -1) {
- const char* version = mReader->getAttributeValue(attrib);
-
- if (!::strncmp(version,"1.5",3)) {
- mFormat = FV_1_5_n;
- DefaultLogger::get()->debug("Collada schema version is 1.5.n");
- }
- else if (!::strncmp(version,"1.4",3)) {
- mFormat = FV_1_4_n;
- DefaultLogger::get()->debug("Collada schema version is 1.4.n");
- }
- else if (!::strncmp(version,"1.3",3)) {
- mFormat = FV_1_3_n;
- DefaultLogger::get()->debug("Collada schema version is 1.3.n");
- }
- }
-
- ReadStructure();
- } else
- {
- DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element \"%s\".") % mReader->getNodeName()));
- SkipElement();
- }
- } else
- {
- // skip everything else silently
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the structure of the file
-void ColladaParser::ReadStructure()
-{
- while ( mReader->read())
- {
- // beginning of elements
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "asset"))
- ReadAssetInfo();
- else if ( IsElement( "library_animations"))
- ReadAnimationLibrary();
- else if ( IsElement( "library_controllers"))
- ReadControllerLibrary();
- else if ( IsElement( "library_images"))
- ReadImageLibrary();
- else if ( IsElement( "library_materials"))
- ReadMaterialLibrary();
- else if ( IsElement( "library_effects"))
- ReadEffectLibrary();
- else if ( IsElement( "library_geometries"))
- ReadGeometryLibrary();
- else if ( IsElement( "library_visual_scenes"))
- ReadSceneLibrary();
- else if ( IsElement( "library_lights"))
- ReadLightLibrary();
- else if ( IsElement( "library_cameras"))
- ReadCameraLibrary();
- else if ( IsElement( "library_nodes"))
- ReadSceneNode(NULL); /* some hacking to reuse this piece of code */
- else if ( IsElement( "scene"))
- ReadScene();
- else
- SkipElement();
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads asset informations such as coordinate system informations and legal blah
-void ColladaParser::ReadAssetInfo()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "unit"))
- {
- // read unit data from the element's attributes
- const int attrIndex = TestAttribute( "meter");
- if (attrIndex == -1) {
- mUnitSize = 1.f;
- }
- else {
- mUnitSize = mReader->getAttributeValueAsFloat( attrIndex);
- }
-
- // consume the trailing stuff
- if ( !mReader->isEmptyElement())
- SkipElement();
- }
- else if ( IsElement( "up_axis"))
- {
- // read content, strip whitespace, compare
- const char* content = GetTextContent();
- if ( strncmp( content, "X_UP", 4) == 0)
- mUpDirection = UP_X;
- else if ( strncmp( content, "Y_UP", 4) == 0)
- mUpDirection = UP_Y;
- else
- mUpDirection = UP_Z;
-
- // check element end
- TestClosing( "up_axis");
- } else
- {
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "asset") != 0)
- ThrowException( "Expected end of \"asset\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the animation library
-void ColladaParser::ReadAnimationLibrary()
-{
- if (mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "animation"))
- {
- // delegate the reading. Depending on the inner elements it will be a container or a anim channel
- ReadAnimation( &mAnims);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "library_animations") != 0)
- ThrowException( "Expected end of \"library_animations\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an animation into the given parent structure
-void ColladaParser::ReadAnimation( Collada::Animation* pParent)
-{
- if ( mReader->isEmptyElement())
- return;
-
- // 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
- typedef std::map<std::string, AnimationChannel> ChannelMap;
- ChannelMap channels;
- // this is the anim container in case we're a container
- Animation* anim = NULL;
-
- // optional name given as an attribute
- std::string animName;
- int indexName = TestAttribute( "name");
- int indexID = TestAttribute( "id");
- if ( indexName >= 0)
- animName = mReader->getAttributeValue( indexName);
- else if ( indexID >= 0)
- animName = mReader->getAttributeValue( indexID);
- else
- animName = "animation";
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // we have subanimations
- if ( IsElement( "animation"))
- {
- // create container from our element
- if ( !anim)
- {
- anim = new Animation;
- anim->mName = animName;
- pParent->mSubAnims.push_back( anim);
- }
-
- // recurse into the subelement
- ReadAnimation( anim);
- }
- else if ( IsElement( "source"))
- {
- // possible animation data - we'll never know. Better store it
- ReadSource();
- }
- else if ( IsElement( "sampler"))
- {
- // read the ID to assign the corresponding collada channel afterwards.
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
- ChannelMap::iterator newChannel = channels.insert( std::make_pair( id, AnimationChannel())).first;
-
- // have it read into a channel
- ReadAnimationSampler( newChannel->second);
- }
- else if ( IsElement( "channel"))
- {
- // the binding element whose whole purpose is to provide the target to animate
- // Thanks, Collada! A directly posted information would have been too simple, I guess.
- // Better add another indirection to that! Can't have enough of those.
- int indexTarget = GetAttribute( "target");
- int indexSource = GetAttribute( "source");
- const char* sourceId = mReader->getAttributeValue( indexSource);
- if ( sourceId[0] == '#')
- sourceId++;
- ChannelMap::iterator cit = channels.find( sourceId);
- if ( cit != channels.end())
- cit->second.mTarget = mReader->getAttributeValue( indexTarget);
-
- if ( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "animation") != 0)
- ThrowException( "Expected end of \"animation\" element.");
-
- break;
- }
- }
-
- // it turned out to have channels - add them
- if ( !channels.empty())
- {
- // special filtering for stupid exporters packing each channel into a separate animation
- if ( channels.size() == 1)
- {
- pParent->mChannels.push_back( channels.begin()->second);
- } else
- {
- // else create the animation, if not done yet, and store the channels
- if ( !anim)
- {
- anim = new Animation;
- anim->mName = animName;
- pParent->mSubAnims.push_back( anim);
- }
- for ( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
- anim->mChannels.push_back( it->second);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an animation sampler into the given anim channel
-void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "input"))
- {
- int indexSemantic = GetAttribute( "semantic");
- const char* semantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( indexSource);
- if ( source[0] != '#')
- ThrowException( "Unsupported URL format");
- source++;
-
- if ( strcmp( semantic, "INPUT") == 0)
- pChannel.mSourceTimes = source;
- else if ( strcmp( semantic, "OUTPUT") == 0)
- pChannel.mSourceValues = source;
-
- if ( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "sampler") != 0)
- ThrowException( "Expected end of \"sampler\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the skeleton controller library
-void ColladaParser::ReadControllerLibrary()
-{
- if (mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "controller"))
- {
- // read ID. Ask the spec if it's neccessary or optional... you might be surprised.
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mControllerLibrary[id] = Controller();
-
- // read on from there
- ReadController( mControllerLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "library_controllers") != 0)
- ThrowException( "Expected end of \"library_controllers\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a controller into the given mesh structure
-void ColladaParser::ReadController( Collada::Controller& pController)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // two types of controllers: "skin" and "morph". Only the first one is relevant, we skip the other
- if ( IsElement( "morph"))
- {
- // should skip everything inside, so there's no danger of catching elements inbetween
- SkipElement();
- }
- else if ( IsElement( "skin"))
- {
- // read the mesh it refers to. According to the spec this could also be another
- // controller, but I refuse to implement every bullshit idea they've come up with
- int sourceIndex = GetAttribute( "source");
- pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1;
- }
- else if ( IsElement( "bind_shape_matrix"))
- {
- // content is 16 floats to define a matrix... it seems to be important for some models
- const char* content = GetTextContent();
-
- // read the 16 floats
- for ( unsigned int a = 0; a < 16; a++)
- {
- // read a number
- content = fast_atof_move( content, pController.mBindShapeMatrix[a]);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- TestClosing( "bind_shape_matrix");
- }
- else if ( IsElement( "source"))
- {
- // data array - we have specialists to handle this
- ReadSource();
- }
- else if ( IsElement( "joints"))
- {
- ReadControllerJoints( pController);
- }
- else if ( IsElement( "vertex_weights"))
- {
- ReadControllerWeights( pController);
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "controller") == 0)
- break;
- else if ( strcmp( mReader->getNodeName(), "skin") != 0)
- ThrowException( "Expected end of \"controller\" element.");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the joint definitions for the given controller
-void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX"
- if ( IsElement( "input"))
- {
- int indexSemantic = GetAttribute( "semantic");
- const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* attrSource = mReader->getAttributeValue( indexSource);
-
- // local URLS always start with a '#'. We don't support global URLs
- if ( attrSource[0] != '#')
- ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource));
- attrSource++;
-
- // parse source URL to corresponding source
- if ( strcmp( attrSemantic, "JOINT") == 0)
- pController.mJointNameSource = attrSource;
- else if ( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0)
- pController.mJointOffsetMatrixSource = attrSource;
- else
- ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in joint data") % attrSemantic));
-
- // skip inner data, if present
- if ( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "joints") != 0)
- ThrowException( "Expected end of \"joints\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the joint weights for the given controller
-void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
-{
- // read vertex count from attributes and resize the array accordingly
- int indexCount = GetAttribute( "count");
- size_t vertexCount = (size_t) mReader->getAttributeValueAsInt( indexCount);
- pController.mWeightCounts.resize( vertexCount);
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT"
- if ( IsElement( "input"))
- {
- InputChannel channel;
-
- int indexSemantic = GetAttribute( "semantic");
- const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* attrSource = mReader->getAttributeValue( indexSource);
- int indexOffset = TestAttribute( "offset");
- if ( indexOffset >= 0)
- channel.mOffset = mReader->getAttributeValueAsInt( indexOffset);
-
- // local URLS always start with a '#'. We don't support global URLs
- if ( attrSource[0] != '#')
- ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource));
- channel.mAccessor = attrSource + 1;
-
- // parse source URL to corresponding source
- if ( strcmp( attrSemantic, "JOINT") == 0)
- pController.mWeightInputJoints = channel;
- else if ( strcmp( attrSemantic, "WEIGHT") == 0)
- pController.mWeightInputWeights = channel;
- else
- ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in vertex_weight data") % attrSemantic));
-
- // skip inner data, if present
- if ( !mReader->isEmptyElement())
- SkipElement();
- }
- else if ( IsElement( "vcount"))
- {
- // read weight count per vertex
- const char* text = GetTextContent();
- size_t numWeights = 0;
- for ( std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it)
- {
- if ( *text == 0)
- ThrowException( "Out of data while reading vcount");
-
- *it = strtol10( text, &text);
- numWeights += *it;
- SkipSpacesAndLineEnd( &text);
- }
-
- TestClosing( "vcount");
-
- // reserve weight count
- pController.mWeights.resize( numWeights);
- }
- else if ( IsElement( "v"))
- {
- // read JointIndex - WeightIndex pairs
- const char* text = GetTextContent();
-
- for ( std::vector< std::pair<size_t, size_t> >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it)
- {
- if ( *text == 0)
- ThrowException( "Out of data while reading vertex_weights");
- it->first = strtol10( text, &text);
- SkipSpacesAndLineEnd( &text);
- if ( *text == 0)
- ThrowException( "Out of data while reading vertex_weights");
- it->second = strtol10( text, &text);
- SkipSpacesAndLineEnd( &text);
- }
-
- TestClosing( "v");
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "vertex_weights") != 0)
- ThrowException( "Expected end of \"vertex_weights\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the image library contents
-void ColladaParser::ReadImageLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "image"))
- {
- // read ID. Another entry which is "optional" by design but obligatory in reality
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mImageLibrary[id] = Image();
-
- // read on from there
- ReadImage( mImageLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "library_images") != 0)
- ThrowException( "Expected end of \"library_images\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an image entry into the given image
-void ColladaParser::ReadImage( Collada::Image& pImage)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT){
- // Need to run different code paths here, depending on the Collada XSD version
- if (IsElement("image")) {
- SkipElement();
- }
- else if ( IsElement( "init_from"))
- {
- if (mFormat == FV_1_4_n)
- {
- // FIX: C4D exporter writes empty <init_from/> tags
- if (!mReader->isEmptyElement()) {
- // element content is filename - hopefully
- const char* sz = TestTextContent();
- if (sz)pImage.mFileName = sz;
- TestClosing( "init_from");
- }
- if (!pImage.mFileName.length()) {
- 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 attrib = TestAttribute("array_index");
- if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
- DefaultLogger::get()->warn("Collada: Ignoring texture array index");
- continue;
- }
-
- attrib = TestAttribute("mip_index");
- if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
- DefaultLogger::get()->warn("Collada: Ignoring MIP map layer");
- continue;
- }
-
- // TODO: correctly jump over cube and volume maps?
- }
- }
- else if (mFormat == FV_1_5_n)
- {
- if ( IsElement( "ref"))
- {
- // element content is filename - hopefully
- const char* sz = TestTextContent();
- if (sz)pImage.mFileName = sz;
- TestClosing( "ref");
- }
- else if ( IsElement( "hex") && !pImage.mFileName.length())
- {
- // embedded image. get format
- const int attrib = TestAttribute("format");
- if (-1 == attrib)
- DefaultLogger::get()->warn("Collada: Unknown image file format");
- else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib);
-
- const char* data = GetTextContent();
-
- // hexadecimal-encoded binary octets. First of all, find the
- // required buffer size to reserve enough storage.
- const char* cur = data;
- while (!IsSpaceOrNewLine(*cur)) cur++;
-
- const unsigned int size = (unsigned int)(cur-data) * 2;
- pImage.mImageData.resize(size);
- for (unsigned int i = 0; i < size;++i)
- pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1));
-
- TestClosing( "hex");
- }
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "image") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the material library
-void ColladaParser::ReadMaterialLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "material"))
- {
- // read ID. By now you propably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- ReadMaterial(mMaterialLibrary[id] = Material());
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "library_materials") != 0)
- ThrowException( "Expected end of \"library_materials\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the light library
-void ColladaParser::ReadLightLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "light"))
- {
- // read ID. By now you propably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- ReadLight(mLightLibrary[id] = Light());
-
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "library_lights") != 0)
- ThrowException( "Expected end of \"library_lights\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the camera library
-void ColladaParser::ReadCameraLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "camera"))
- {
- // read ID. By now you propably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- Camera& cam = mCameraLibrary[id];
- attrID = TestAttribute( "name");
- if (attrID != -1)
- cam.mName = mReader->getAttributeValue( attrID);
-
- ReadCamera(cam);
-
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "library_cameras") != 0)
- ThrowException( "Expected end of \"library_cameras\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a material entry into the given material
-void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("material")) {
- SkipElement();
- }
- else if ( IsElement( "instance_effect"))
- {
- // referred effect by URL
- int attrUrl = GetAttribute( "url");
- const char* url = mReader->getAttributeValue( attrUrl);
- if ( url[0] != '#')
- ThrowException( "Unknown reference format");
-
- pMaterial.mEffect = url+1;
-
- SkipElement();
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "material") != 0)
- ThrowException( "Expected end of \"material\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a light entry into the given light
-void ColladaParser::ReadLight( Collada::Light& pLight)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("light")) {
- SkipElement();
- }
- else if (IsElement("spot")) {
- pLight.mType = aiLightSource_SPOT;
- }
- else if (IsElement("ambient")) {
- pLight.mType = aiLightSource_AMBIENT;
- }
- else if (IsElement("directional")) {
- pLight.mType = aiLightSource_DIRECTIONAL;
- }
- else if (IsElement("point")) {
- pLight.mType = aiLightSource_POINT;
- }
- else if (IsElement("color")) {
- // text content contains 3 floats
- const char* content = GetTextContent();
-
- content = fast_atof_move( content, (float&)pLight.mColor.r);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atof_move( content, (float&)pLight.mColor.g);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atof_move( content, (float&)pLight.mColor.b);
- SkipSpacesAndLineEnd( &content);
-
- TestClosing( "color");
- }
- else if (IsElement("constant_attenuation")) {
- pLight.mAttConstant = ReadFloatFromTextContent();
- TestClosing("constant_attenuation");
- }
- else if (IsElement("linear_attenuation")) {
- pLight.mAttLinear = ReadFloatFromTextContent();
- TestClosing("linear_attenuation");
- }
- else if (IsElement("quadratic_attenuation")) {
- pLight.mAttQuadratic = ReadFloatFromTextContent();
- TestClosing("quadratic_attenuation");
- }
- else if (IsElement("falloff_angle")) {
- pLight.mFalloffAngle = ReadFloatFromTextContent();
- TestClosing("falloff_angle");
- }
- else if (IsElement("falloff_exponent")) {
- pLight.mFalloffExponent = ReadFloatFromTextContent();
- TestClosing("falloff_exponent");
- }
- // FCOLLADA extensions
- // -------------------------------------------------------
- else if (IsElement("outer_cone")) {
- pLight.mOuterAngle = ReadFloatFromTextContent();
- TestClosing("outer_cone");
- }
- // ... and this one is even deprecated
- else if (IsElement("penumbra_angle")) {
- pLight.mPenumbraAngle = ReadFloatFromTextContent();
- TestClosing("penumbra_angle");
- }
- else if (IsElement("intensity")) {
- pLight.mIntensity = ReadFloatFromTextContent();
- TestClosing("intensity");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "light") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a camera entry into the given light
-void ColladaParser::ReadCamera( Collada::Camera& pCamera)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("camera")) {
- SkipElement();
- }
- else if (IsElement("orthographic")) {
- pCamera.mOrtho = true;
- }
- else if (IsElement("xfov") || IsElement("xmag")) {
- pCamera.mHorFov = ReadFloatFromTextContent();
- TestClosing((pCamera.mOrtho ? "xmag" : "xfov"));
- }
- else if (IsElement("yfov") || IsElement("ymag")) {
- pCamera.mVerFov = ReadFloatFromTextContent();
- TestClosing((pCamera.mOrtho ? "ymag" : "yfov"));
- }
- else if (IsElement("aspect_ratio")) {
- pCamera.mAspect = ReadFloatFromTextContent();
- TestClosing("aspect_ratio");
- }
- else if (IsElement("znear")) {
- pCamera.mZNear = ReadFloatFromTextContent();
- TestClosing("znear");
- }
- else if (IsElement("zfar")) {
- pCamera.mZFar = ReadFloatFromTextContent();
- TestClosing("zfar");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "camera") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the effect library
-void ColladaParser::ReadEffectLibrary()
-{
- if (mReader->isEmptyElement()) {
- return;
- }
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "effect"))
- {
- // read ID. Do I have to repeat my ranting about "optional" attributes?
- // Alex: .... no, not necessary. Please shut up and leave more space for
- // me to complain about the fucking Collada spec with its fucking
- // 'optional' attributes ...
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mEffectLibrary[id] = Effect();
- // read on from there
- ReadEffect( mEffectLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "library_effects") != 0)
- ThrowException( "Expected end of \"library_effects\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry into the given effect
-void ColladaParser::ReadEffect( Collada::Effect& pEffect)
-{
- // for the moment we don't support any other type of effect.
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "profile_COMMON"))
- ReadEffectProfileCommon( pEffect);
- else
- SkipElement();
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "effect") != 0)
- ThrowException( "Expected end of \"effect\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an COMMON effect profile
-void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "newparam")) {
- // save ID
- int attrSID = GetAttribute( "sid");
- std::string sid = mReader->getAttributeValue( attrSID);
- pEffect.mParams[sid] = EffectParam();
- ReadEffectParam( pEffect.mParams[sid]);
- }
- else if ( IsElement( "technique") || IsElement( "extra"))
- {
- // just syntactic sugar
- }
-
- /* Shading modes */
- else if ( IsElement( "phong"))
- pEffect.mShadeType = Shade_Phong;
- else if ( IsElement( "constant"))
- pEffect.mShadeType = Shade_Constant;
- else if ( IsElement( "lambert"))
- pEffect.mShadeType = Shade_Lambert;
- else if ( IsElement( "blinn"))
- pEffect.mShadeType = Shade_Blinn;
-
- /* Color + texture properties */
- else if ( IsElement( "emission"))
- ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive);
- else if ( IsElement( "ambient"))
- ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient);
- else if ( IsElement( "diffuse"))
- ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse);
- else if ( IsElement( "specular"))
- ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular);
- else if ( IsElement( "reflective")) {
- ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective);
- }
- else if ( IsElement( "transparent")) {
- ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent);
- }
- else if ( IsElement( "shininess"))
- ReadEffectFloat( pEffect.mShininess);
- else if ( IsElement( "reflectivity"))
- ReadEffectFloat( pEffect.mReflectivity);
-
- /* Single scalar properties */
- else if ( IsElement( "transparency"))
- ReadEffectFloat( pEffect.mTransparency);
- else if ( IsElement( "index_of_refraction"))
- ReadEffectFloat( pEffect.mRefractIndex);
-
- // GOOGLEEARTH/OKINO extensions
- // -------------------------------------------------------
- else if ( IsElement( "double_sided"))
- pEffect.mDoubleSided = ReadBoolFromTextContent();
-
- // FCOLLADA extensions
- // -------------------------------------------------------
- else if ( IsElement( "bump")) {
- aiColor4D dummy;
- ReadEffectColor( dummy,pEffect.mTexBump);
- }
-
- // MAX3D extensions
- // -------------------------------------------------------
- else if ( IsElement( "wireframe")) {
- pEffect.mWireframe = ReadBoolFromTextContent();
- TestClosing( "wireframe");
- }
- else if ( IsElement( "faceted")) {
- pEffect.mFaceted = ReadBoolFromTextContent();
- TestClosing( "faceted");
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "profile_COMMON") == 0)
- {
- break;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read texture wrapping + UV transform settings from a profile==Maya chunk
-void ColladaParser::ReadSamplerProperties( Sampler& out )
-{
- if (mReader->isEmptyElement()) {
- return;
- }
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
-
- // MAYA extensions
- // -------------------------------------------------------
- if ( IsElement( "wrapU")) {
- out.mWrapU = ReadBoolFromTextContent();
- TestClosing( "wrapU");
- }
- else if ( IsElement( "wrapV")) {
- out.mWrapU = ReadBoolFromTextContent();
- TestClosing( "wrapV");
- }
- else if ( IsElement( "mirrorU")) {
- out.mMirrorU = ReadBoolFromTextContent();
- TestClosing( "mirrorU");
- }
- else if ( IsElement( "mirrorV")) {
- out.mMirrorU = ReadBoolFromTextContent();
- TestClosing( "mirrorV");
- }
- else if ( IsElement( "repeatU")) {
- out.mTransform.mScaling.x = ReadFloatFromTextContent();
- TestClosing( "repeatU");
- }
- else if ( IsElement( "repeatV")) {
- out.mTransform.mScaling.y = ReadFloatFromTextContent();
- TestClosing( "repeatV");
- }
- else if ( IsElement( "offsetU")) {
- out.mTransform.mTranslation.x = ReadFloatFromTextContent();
- TestClosing( "offsetU");
- }
- else if ( IsElement( "offsetV")) {
- out.mTransform.mTranslation.x = ReadFloatFromTextContent();
- TestClosing( "offsetV");
- }
- else if ( IsElement( "rotateUV")) {
- out.mTransform.mRotation = ReadFloatFromTextContent();
- TestClosing( "rotateUV");
- }
- else if ( IsElement( "blend_mode")) {
-
- const char* sz = GetTextContent();
- // http://www.feelingsoftware.com/content/view/55/72/lang,en/
- // NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
- if (0 == ASSIMP_strincmp(sz,"ADD",3))
- out.mOp = aiTextureOp_Add;
-
- else if (0 == ASSIMP_strincmp(sz,"SUBTRACT",8))
- out.mOp = aiTextureOp_Subtract;
-
- else if (0 == ASSIMP_strincmp(sz,"MULTIPLY",8))
- out.mOp = aiTextureOp_Multiply;
-
- else {
- DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode");
- }
- TestClosing( "blend_mode");
- }
- // OKINO extensions
- // -------------------------------------------------------
- else if ( IsElement( "weighting")) {
- out.mWeighting = ReadFloatFromTextContent();
- TestClosing( "weighting");
- }
- else if ( IsElement( "mix_with_previous_layer")) {
- out.mMixWithPrevious = ReadFloatFromTextContent();
- TestClosing( "mix_with_previous_layer");
- }
- // MAX3D extensions
- // -------------------------------------------------------
- else if ( IsElement( "amount")) {
- out.mWeighting = ReadFloatFromTextContent();
- TestClosing( "amount");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "technique") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry containing a color or a texture defining that color
-void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
-{
- if (mReader->isEmptyElement())
- return;
-
- // Save current element name
- const std::string curElem = mReader->getNodeName();
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "color"))
- {
- // text content contains 4 floats
- const char* content = GetTextContent();
-
- content = fast_atof_move( content, (float&)pColor.r);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atof_move( content, (float&)pColor.g);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atof_move( content, (float&)pColor.b);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atof_move( content, (float&)pColor.a);
- SkipSpacesAndLineEnd( &content);
- TestClosing( "color");
- }
- else if ( IsElement( "texture"))
- {
- // get name of source textur/sampler
- int attrTex = GetAttribute( "texture");
- pSampler.mName = mReader->getAttributeValue( attrTex);
-
- // get name of UV source channel
- attrTex = GetAttribute( "texcoord");
- pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
- //SkipElement();
- }
- else if ( IsElement( "technique"))
- {
- const int _profile = GetAttribute( "profile");
- const char* profile = mReader->getAttributeValue( _profile );
-
- // Some extensions are quite useful ... ReadSamplerProperties processes
- // several extensions in MAYA, OKINO and MAX3D profiles.
- if (!::strcmp(profile,"MAYA") || !::strcmp(profile,"MAX3D") || !::strcmp(profile,"OKINO"))
- {
- // get more information on this sampler
- ReadSamplerProperties(pSampler);
- }
- else SkipElement();
- }
- else if ( !IsElement( "extra"))
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- if (mReader->getNodeName() == curElem)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry containing a float
-void ColladaParser::ReadEffectFloat( float& pFloat)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT){
- if ( IsElement( "float"))
- {
- // text content contains a single floats
- const char* content = GetTextContent();
- content = fast_atof_move( content, pFloat);
- SkipSpacesAndLineEnd( &content);
-
- TestClosing( "float");
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect parameter specification of any kind
-void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "surface"))
- {
- // image ID given inside <init_from> tags
- TestOpening( "init_from");
- const char* content = GetTextContent();
- pParam.mType = Param_Surface;
- pParam.mReference = content;
- TestClosing( "init_from");
-
- // don't care for remaining stuff
- SkipElement( "surface");
- }
- else if ( IsElement( "sampler2D"))
- {
- // surface ID is given inside <source> tags
- TestOpening( "source");
- const char* content = GetTextContent();
- pParam.mType = Param_Sampler;
- pParam.mReference = content;
- TestClosing( "source");
-
- // don't care for remaining stuff
- SkipElement( "sampler2D");
- } else
- {
- // ignore unknown element
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the geometry library contents
-void ColladaParser::ReadGeometryLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "geometry"))
- {
- // read ID. Another entry which is "optional" by design but obligatory in reality
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
-
- // TODO: (thom) support SIDs
- // ai_assert( TestAttribute( "sid") == -1);
-
- // create a mesh and store it in the library under its ID
- Mesh* mesh = new Mesh;
- mMeshLibrary[id] = mesh;
-
- // read on from there
- ReadGeometry( mesh);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "library_geometries") != 0)
- ThrowException( "Expected end of \"library_geometries\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a geometry from the geometry library.
-void ColladaParser::ReadGeometry( Collada::Mesh* pMesh)
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "mesh"))
- {
- // read on from there
- ReadMesh( pMesh);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "geometry") != 0)
- ThrowException( "Expected end of \"geometry\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a mesh from the geometry library
-void ColladaParser::ReadMesh( Mesh* pMesh)
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "source"))
- {
- // we have professionals dealing with this
- ReadSource();
- }
- else if ( IsElement( "vertices"))
- {
- // read per-vertex mesh data
- ReadVertexData( pMesh);
- }
- else if ( IsElement( "triangles") || IsElement( "lines") || IsElement( "linestrips")
- || IsElement( "polygons") || IsElement( "polylist") || IsElement( "trifans") || IsElement( "tristrips"))
- {
- // read per-index mesh data and faces setup
- ReadIndexData( pMesh);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "technique_common") == 0)
- {
- // end of another meaningless element - read over it
- }
- else if ( strcmp( mReader->getNodeName(), "mesh") == 0)
- {
- // end of <mesh> element - we're done here
- break;
- } else
- {
- // everything else should be punished
- ThrowException( "Expected end of \"mesh\" element.");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a source element
-void ColladaParser::ReadSource()
-{
- int indexID = GetAttribute( "id");
- std::string sourceID = mReader->getAttributeValue( indexID);
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array"))
- {
- ReadDataArray();
- }
- else if ( IsElement( "technique_common"))
- {
- // I don't fucking care for your profiles bullshit
- }
- else if ( IsElement( "accessor"))
- {
- ReadAccessor( sourceID);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "source") == 0)
- {
- // end of <source> - we're done
- break;
- }
- else if ( strcmp( mReader->getNodeName(), "technique_common") == 0)
- {
- // end of another meaningless element - read over it
- } else
- {
- // everything else should be punished
- ThrowException( "Expected end of \"source\" element.");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a data array holding a number of floats, and stores it in the global library
-void ColladaParser::ReadDataArray()
-{
- std::string elmName = mReader->getNodeName();
- bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
-
- // read attributes
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
- int indexCount = GetAttribute( "count");
- unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount);
- const char* content = TestTextContent();
- if (content) { // some exporters write empty data arrays, silently skip over them
-
- // read values and store inside an array in the data library
- mDataLibrary[id] = Data();
- Data& data = mDataLibrary[id];
- data.mIsStringArray = isStringArray;
-
- if ( isStringArray)
- {
- data.mStrings.reserve( count);
- std::string s;
-
- for ( unsigned int a = 0; a < count; a++)
- {
- if ( *content == 0)
- ThrowException( "Expected more values while reading IDREF_array contents.");
-
- s.clear();
- while ( !IsSpaceOrNewLine( *content))
- s += *content++;
- data.mStrings.push_back( s);
-
- SkipSpacesAndLineEnd( &content);
- }
- } else
- {
- data.mValues.reserve( count);
-
- for ( unsigned int a = 0; a < count; a++)
- {
- if ( *content == 0)
- ThrowException( "Expected more values while reading float_array contents.");
-
- float value;
- // read a number
- content = fast_atof_move( content, value);
- data.mValues.push_back( value);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
- }
- }
-
- // test for closing tag
- TestClosing( elmName.c_str());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an accessor and stores it in the global library
-void ColladaParser::ReadAccessor( const std::string& pID)
-{
- // read accessor attributes
- int attrSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( attrSource);
- if ( source[0] != '#')
- ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
- int attrCount = GetAttribute( "count");
- unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
- int attrOffset = TestAttribute( "offset");
- unsigned int offset = 0;
- if ( attrOffset > -1)
- offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset);
- int attrStride = TestAttribute( "stride");
- unsigned int stride = 1;
- if ( attrStride > -1)
- stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride);
-
- // store in the library under the given ID
- mAccessorLibrary[pID] = Accessor();
- Accessor& acc = mAccessorLibrary[pID];
- acc.mCount = count;
- acc.mOffset = offset;
- acc.mStride = stride;
- acc.mSource = source+1; // ignore the leading '#'
- acc.mSize = 0; // gets incremented with every param
-
- // and read the components
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "param"))
- {
- // read data param
- int attrName = TestAttribute( "name");
- std::string name;
- if ( attrName > -1)
- {
- name = mReader->getAttributeValue( attrName);
-
- // analyse for common type components and store it's sub-offset in the corresponding field
-
- /* Cartesian coordinates */
- if ( name == "X") acc.mSubOffset[0] = acc.mParams.size();
- else if ( name == "Y") acc.mSubOffset[1] = acc.mParams.size();
- else if ( name == "Z") acc.mSubOffset[2] = acc.mParams.size();
-
- /* RGBA colors */
- else if ( name == "R") acc.mSubOffset[0] = acc.mParams.size();
- else if ( name == "G") acc.mSubOffset[1] = acc.mParams.size();
- else if ( name == "B") acc.mSubOffset[2] = acc.mParams.size();
- else if ( name == "A") acc.mSubOffset[3] = acc.mParams.size();
-
- /* UVWQ (STPQ) texture coordinates */
- else if ( name == "S") acc.mSubOffset[0] = acc.mParams.size();
- else if ( name == "T") acc.mSubOffset[1] = acc.mParams.size();
- else if ( name == "P") 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*/
- else if ( name == "U") acc.mSubOffset[0] = acc.mParams.size();
- else if ( name == "V") acc.mSubOffset[1] = acc.mParams.size();
- //else
- // DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name));
- }
-
- // read data type
- int attrType = TestAttribute( "type");
- if ( attrType > -1)
- {
- // for the moment we only distinguish between a 4x4 matrix and anything else.
- // TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types
- // which should be tested for here.
- std::string type = mReader->getAttributeValue( attrType);
- if ( type == "float4x4")
- acc.mSize += 16;
- else
- acc.mSize += 1;
- }
-
- acc.mParams.push_back( name);
-
- // skip remaining stuff of this element, if any
- SkipElement();
- } else
- {
- ThrowException( "Unexpected sub element in tag \"accessor\".");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "accessor") != 0)
- ThrowException( "Expected end of \"accessor\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads input declarations of per-vertex mesh data into the given mesh
-void ColladaParser::ReadVertexData( Mesh* pMesh)
-{
- // extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
- int attrID= GetAttribute( "id");
- pMesh->mVertexID = mReader->getAttributeValue( attrID);
-
- // a number of <input> elements
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "input"))
- {
- ReadInputChannel( pMesh->mPerVertexData);
- } else
- {
- ThrowException( "Unexpected sub element in tag \"vertices\".");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "vertices") != 0)
- ThrowException( "Expected end of \"vertices\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads input declarations of per-index mesh data into the given mesh
-void ColladaParser::ReadIndexData( Mesh* pMesh)
-{
- std::vector<size_t> vcount;
- std::vector<InputChannel> perIndexData;
-
- // read primitive count from the attribute
- int attrCount = GetAttribute( "count");
- size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
-
- // material subgroup
- int attrMaterial = TestAttribute( "material");
- SubMesh subgroup;
- if ( attrMaterial > -1)
- subgroup.mMaterial = mReader->getAttributeValue( attrMaterial);
- subgroup.mNumFaces = numPrimitives;
- pMesh->mSubMeshes.push_back( subgroup);
-
- // distinguish between polys and triangles
- std::string elementName = mReader->getNodeName();
- PrimitiveType primType = Prim_Invalid;
- if ( IsElement( "lines"))
- primType = Prim_Lines;
- else if ( IsElement( "linestrips"))
- primType = Prim_LineStrip;
- else if ( IsElement( "polygons"))
- primType = Prim_Polygon;
- else if ( IsElement( "polylist"))
- primType = Prim_Polylist;
- else if ( IsElement( "triangles"))
- primType = Prim_Triangles;
- else if ( IsElement( "trifans"))
- primType = Prim_TriFans;
- else if ( IsElement( "tristrips"))
- primType = Prim_TriStrips;
-
- ai_assert( primType != Prim_Invalid);
-
- // also a number of <input> elements, but in addition a <p> primitive collection and propably index counts for all primitives
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "input"))
- {
- ReadInputChannel( perIndexData);
- }
- else if ( IsElement( "vcount"))
- {
- if ( !mReader->isEmptyElement())
- {
- // case <polylist> - specifies the number of indices for each polygon
- const char* content = GetTextContent();
- vcount.reserve( numPrimitives);
- for ( unsigned int a = 0; a < numPrimitives; a++)
- {
- if ( *content == 0)
- ThrowException( "Expected more values while reading vcount contents.");
- // read a number
- vcount.push_back( (size_t) strtol10( content, &content));
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- TestClosing( "vcount");
- }
- }
- else if ( IsElement( "p"))
- {
- if ( !mReader->isEmptyElement())
- {
- // now here the actual fun starts - these are the indices to construct the mesh data from
- ReadPrimitives( pMesh, perIndexData, numPrimitives, vcount, primType);
- }
- } else
- {
- ThrowException( "Unexpected sub element in tag \"vertices\".");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( mReader->getNodeName() != elementName)
- ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % elementName));
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a single input channel element and stores it in the given array, if valid
-void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
-{
- InputChannel channel;
-
- // read semantic
- int attrSemantic = GetAttribute( "semantic");
- std::string semantic = mReader->getAttributeValue( attrSemantic);
- channel.mType = GetTypeForSemantic( semantic);
-
- // read source
- int attrSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( attrSource);
- if ( source[0] != '#')
- ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
- channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
-
- // read index offset, if per-index <input>
- int attrOffset = TestAttribute( "offset");
- if ( attrOffset > -1)
- channel.mOffset = mReader->getAttributeValueAsInt( attrOffset);
-
- // read set if texture coordinates
- if (channel.mType == IT_Texcoord || channel.mType == IT_Color){
- int attrSet = TestAttribute("set");
- if (attrSet > -1){
- attrSet = mReader->getAttributeValueAsInt( attrSet);
- if (attrSet < 0)
- ThrowException( boost::str( boost::format( "Invalid index \"%i\" for set attribute") % (attrSet)));
-
- channel.mIndex = attrSet;
- }
- }
-
- // store, if valid type
- if ( channel.mType != IT_Invalid)
- poChannels.push_back( channel);
-
- // skip remaining stuff of this element, if any
- SkipElement();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a <p> primitive index list and assembles the mesh data into the given mesh
-void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
- size_t pNumPrimitives, const std::vector<size_t>& pVCount, PrimitiveType pPrimType)
-{
- // determine number of indices coming per vertex
- // find the offset index for all per-vertex channels
- size_t numOffsets = 1;
- size_t perVertexOffset = 0xffffffff; // invalid value
- BOOST_FOREACH( const InputChannel& channel, pPerIndexChannels)
- {
- numOffsets = std::max( numOffsets, channel.mOffset+1);
- if ( channel.mType == IT_Vertex)
- perVertexOffset = channel.mOffset;
- }
-
- // determine the expected number of indices
- size_t expectedPointCount = 0;
- switch( pPrimType)
- {
- case Prim_Polylist:
- {
- BOOST_FOREACH( size_t i, pVCount)
- expectedPointCount += i;
- break;
- }
- case Prim_Lines:
- expectedPointCount = 2 * pNumPrimitives;
- break;
- case Prim_Triangles:
- expectedPointCount = 3 * pNumPrimitives;
- break;
- default:
- // other primitive types don't state the index count upfront... we need to guess
- break;
- }
-
- // and read all indices into a temporary array
- std::vector<size_t> indices;
- if ( expectedPointCount > 0)
- indices.reserve( expectedPointCount * numOffsets);
-
- const char* content = GetTextContent();
- while ( *content != 0)
- {
- // read a value.
- // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
- int value = std::max( 0, strtol10s( content, &content));
- indices.push_back( size_t( value));
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- // complain if the index count doesn't fit
- if ( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets)
- ThrowException( "Expected different index count in <p> element.");
- else if ( expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
- ThrowException( "Expected different index count in <p> element.");
-
- // find the data for all sources
- for ( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
- {
- InputChannel& input = *it;
- if ( input.mResolved)
- continue;
-
- // find accessor
- input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
- // resolve accessor's data pointer as well, if neccessary
- const Accessor* acc = input.mResolved;
- if ( !acc->mData)
- acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
- }
- // and the same for the per-index channels
- for ( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
- {
- InputChannel& input = *it;
- if ( input.mResolved)
- continue;
-
- // ignore vertex pointer, it doesn't refer to an accessor
- if ( input.mType == IT_Vertex)
- {
- // warn if the vertex channel does not refer to the <vertices> element in the same mesh
- if ( input.mAccessor != pMesh->mVertexID)
- ThrowException( "Unsupported vertex referencing scheme. I fucking hate Collada.");
- continue;
- }
-
- // find accessor
- input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
- // resolve accessor's data pointer as well, if neccessary
- const Accessor* acc = input.mResolved;
- if ( !acc->mData)
- acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
- }
-
-
- // now assemble vertex data according to those indices
- std::vector<size_t>::const_iterator idx = indices.begin();
-
- // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
- size_t numPrimitives = pNumPrimitives;
- if ( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
- numPrimitives = 1;
-
- pMesh->mFaceSize.reserve( numPrimitives);
- pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
-
- for ( size_t a = 0; a < numPrimitives; a++)
- {
- // determine number of points for this primitive
- size_t numPoints = 0;
- switch( pPrimType)
- {
- case Prim_Lines:
- numPoints = 2;
- break;
- case Prim_Triangles:
- numPoints = 3;
- break;
- case Prim_Polylist:
- numPoints = pVCount[a];
- break;
- case Prim_TriFans:
- case Prim_Polygon:
- numPoints = indices.size() / numOffsets;
- break;
- default:
- // LineStrip and TriStrip not supported due to expected index unmangling
- ThrowException( "Unsupported primitive type.");
- break;
- }
-
- // store the face size to later reconstruct the face from
- pMesh->mFaceSize.push_back( numPoints);
-
- // gather that number of vertices
- for ( size_t b = 0; b < numPoints; b++)
- {
- // read all indices for this vertex. Yes, in a hacky local array
- assert( numOffsets < 20 && perVertexOffset < 20);
- size_t vindex[20];
- for ( size_t offsets = 0; offsets < numOffsets; ++offsets)
- vindex[offsets] = *idx++;
-
- // extract per-vertex channels using the global per-vertex offset
- for ( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
- ExtractDataObjectFromChannel( *it, vindex[perVertexOffset], pMesh);
- // and extract per-index channels using there specified offset
- for ( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
- ExtractDataObjectFromChannel( *it, vindex[it->mOffset], pMesh);
-
- // store the vertex-data index for later assignment of bone vertex weights
- pMesh->mFacePosIndices.push_back( vindex[perVertexOffset]);
- }
- }
-
-
- // if I ever get my hands on that guy who invented this steaming pile of indirection...
- TestClosing( "p");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extracts a single object from an input channel and stores it in the appropriate mesh data array
-void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh)
-{
- // ignore vertex referrer - we handle them that separate
- if ( pInput.mType == IT_Vertex)
- return;
-
- const Accessor& acc = *pInput.mResolved;
- if ( pLocalIndex >= acc.mCount)
- ThrowException( boost::str( boost::format( "Invalid data index (%d/%d) in primitive specification") % pLocalIndex % acc.mCount));
-
- // get a pointer to the start of the data object referred to by the accessor and the local index
- const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride;
-
- // assemble according to the accessors component sub-offset list. We don't care, yet,
- // what kind of object exactly we're extracting here
- float obj[4];
- for ( size_t c = 0; c < 4; ++c)
- obj[c] = dataObject[acc.mSubOffset[c]];
-
- // now we reinterpret it according to the type we're reading here
- switch( pInput.mType)
- {
- case IT_Position: // ignore all position streams except 0 - there can be only one position
- if ( pInput.mIndex == 0)
- pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2]));
- else
- DefaultLogger::get()->error("Collada: just one vertex position stream supported");
- break;
- case IT_Normal:
- // pad to current vertex count if necessary
- if ( pMesh->mNormals.size() < pMesh->mPositions.size()-1)
- pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0));
-
- // ignore all normal streams except 0 - there can be only one normal
- if ( pInput.mIndex == 0)
- pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2]));
- else
- DefaultLogger::get()->error("Collada: just one vertex normal stream supported");
- break;
- case IT_Tangent:
- // pad to current vertex count if necessary
- if ( pMesh->mTangents.size() < pMesh->mPositions.size()-1)
- pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0));
-
- // ignore all tangent streams except 0 - there can be only one tangent
- if ( pInput.mIndex == 0)
- pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
- else
- DefaultLogger::get()->error("Collada: just one vertex tangent stream supported");
- break;
- case IT_Bitangent:
- // pad to current vertex count if necessary
- if ( pMesh->mBitangents.size() < pMesh->mPositions.size()-1)
- pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1));
-
- // ignore all bitangent streams except 0 - there can be only one bitangent
- if ( pInput.mIndex == 0)
- pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
- else
- DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported");
- break;
- case IT_Texcoord:
- // up to 4 texture coord sets are fine, ignore the others
- if ( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS)
- {
- // pad to current vertex count if necessary
- if ( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1)
- pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(),
- pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0));
-
- pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2]));
- if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */
- pMesh->mNumUVComponents[pInput.mIndex]=3;
- } else
- {
- DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping.");
- }
- break;
- case IT_Color:
- // up to 4 color sets are fine, ignore the others
- if ( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS)
- {
- // pad to current vertex count if necessary
- if ( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1)
- pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(),
- pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1));
-
- pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
- } else
- {
- DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");
- }
-
- break;
- default:
- // IT_Invalid and IT_Vertex
- ai_assert(false && "shouldn't ever get here");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the library of node hierarchies and scene parts
-void ColladaParser::ReadSceneLibrary()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // a visual scene - generate root node under its ID and let ReadNode() do the recursive work
- if ( IsElement( "visual_scene"))
- {
- // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
- int indexID = GetAttribute( "id");
- const char* attrID = mReader->getAttributeValue( indexID);
-
- // read name if given.
- int indexName = TestAttribute( "name");
- const char* attrName = "unnamed";
- if ( indexName > -1)
- attrName = mReader->getAttributeValue( indexName);
-
- // create a node and store it in the library under its ID
- Node* node = new Node;
- node->mID = attrID;
- node->mName = attrName;
- mNodeLibrary[node->mID] = node;
-
- ReadSceneNode( node);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "library_visual_scenes") == 0)
- //ThrowException( "Expected end of \"library_visual_scenes\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a scene node's contents including children and stores it in the given node
-void ColladaParser::ReadSceneNode( Node* pNode)
-{
- // quit immediately on <bla/> elements
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "node"))
- {
- Node* child = new Node;
- int attrID = TestAttribute( "id");
- if ( attrID > -1)
- child->mID = mReader->getAttributeValue( attrID);
- int attrSID = TestAttribute( "sid");
- if ( attrSID > -1)
- child->mSID = mReader->getAttributeValue( attrSID);
-
- int attrName = TestAttribute( "name");
- if ( attrName > -1)
- child->mName = mReader->getAttributeValue( attrName);
-
- // TODO: (thom) support SIDs
- // assert( TestAttribute( "sid") == -1);
-
- if (pNode)
- {
- pNode->mChildren.push_back( child);
- child->mParent = pNode;
- }
- else
- {
- // no parent node given, probably called from <library_nodes> element.
- // create new node in node library
- mNodeLibrary[child->mID] = child;
- }
-
- // read on recursively from there
- ReadSceneNode( child);
- continue;
- }
- // For any further stuff we need a valid node to work on
- else if (!pNode)
- continue;
-
- if ( IsElement( "lookat"))
- ReadNodeTransformation( pNode, TF_LOOKAT);
- else if ( IsElement( "matrix"))
- ReadNodeTransformation( pNode, TF_MATRIX);
- else if ( IsElement( "rotate"))
- ReadNodeTransformation( pNode, TF_ROTATE);
- else if ( IsElement( "scale"))
- ReadNodeTransformation( pNode, TF_SCALE);
- else if ( IsElement( "skew"))
- ReadNodeTransformation( pNode, TF_SKEW);
- else if ( IsElement( "translate"))
- ReadNodeTransformation( pNode, TF_TRANSLATE);
- else if ( IsElement( "render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length())
- {
- // ... scene evaluation or, in other words, postprocessing pipeline,
- // or, again in other words, a turing-complete description how to
- // render a Collada scene. The only thing that is interesting for
- // us is the primary camera.
- int attrId = TestAttribute("camera_node");
- if (-1 != attrId)
- {
- const char* s = mReader->getAttributeValue(attrId);
- if (s[0] != '#')
- DefaultLogger::get()->error("Collada: Unresolved reference format of camera");
- else
- pNode->mPrimaryCamera = s+1;
- }
- }
- else if ( IsElement( "instance_node"))
- {
- // find the node in the library
- int attrID = TestAttribute( "url");
- if ( attrID != -1)
- {
- const char* s = mReader->getAttributeValue(attrID);
- if (s[0] != '#')
- DefaultLogger::get()->error("Collada: Unresolved reference format of node");
- else
- {
- pNode->mNodeInstances.push_back(NodeInstance());
- pNode->mNodeInstances.back().mNode = s+1;
- }
- }
- }
- else if ( IsElement( "instance_geometry") || IsElement( "instance_controller"))
- {
- // Reference to a mesh or controller, with possible material associations
- ReadNodeGeometry( pNode);
- }
- else if ( IsElement( "instance_light"))
- {
- // Reference to a light, name given in 'url' attribute
- int attrID = TestAttribute("url");
- if (-1 == attrID)
- DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_light> element");
- else
- {
- const char* url = mReader->getAttributeValue( attrID);
- if ( url[0] != '#')
- ThrowException( "Unknown reference format in <instance_light> element");
-
- pNode->mLights.push_back(LightInstance());
- pNode->mLights.back().mLight = url+1;
- }
- }
- else if ( IsElement( "instance_camera"))
- {
- // Reference to a camera, name given in 'url' attribute
- int attrID = TestAttribute("url");
- if (-1 == attrID)
- DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_camera> element");
- else
- {
- const char* url = mReader->getAttributeValue( attrID);
- if ( url[0] != '#')
- ThrowException( "Unknown reference format in <instance_camera> element");
-
- pNode->mCameras.push_back(CameraInstance());
- pNode->mCameras.back().mCamera = url+1;
- }
- }
- else
- {
- // skip everything else for the moment
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
-void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType)
-{
- if ( mReader->isEmptyElement())
- return;
-
- std::string tagName = mReader->getNodeName();
-
- Transform tf;
- tf.mType = pType;
-
- // read SID
- int indexSID = TestAttribute( "sid");
- if ( indexSID >= 0)
- tf.mID = mReader->getAttributeValue( indexSID);
-
- // how many parameters to read per transformation type
- static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
- const char* content = GetTextContent();
-
- // read as many parameters and store in the transformation
- for ( unsigned int a = 0; a < sNumParameters[pType]; a++)
- {
- // read a number
- content = fast_atof_move( content, tf.f[a]);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- // place the transformation at the queue of the node
- pNode->mTransforms.push_back( tf);
-
- // and consume the closing tag
- TestClosing( tagName.c_str());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Processes bind_vertex_input and bind elements
-void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl)
-{
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "bind_vertex_input"))
- {
- Collada::InputSemanticMapEntry vn;
-
- // effect semantic
- int n = GetAttribute("semantic");
- std::string s = mReader->getAttributeValue(n);
-
- // input semantic
- n = GetAttribute("input_semantic");
- vn.mType = GetTypeForSemantic( mReader->getAttributeValue(n) );
-
- // index of input set
- n = TestAttribute("input_set");
- if (-1 != n)
- vn.mSet = mReader->getAttributeValueAsInt(n);
-
- tbl.mMap[s] = vn;
- }
- else if ( IsElement( "bind")) {
- DefaultLogger::get()->warn("Collada: Found unsupported <bind> element");
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if ( strcmp( mReader->getNodeName(), "instance_material") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a mesh reference in a node and adds it to the node's mesh list
-void ColladaParser::ReadNodeGeometry( Node* pNode)
-{
- // referred mesh is given as an attribute of the <instance_geometry> element
- int attrUrl = GetAttribute( "url");
- const char* url = mReader->getAttributeValue( attrUrl);
- if ( url[0] != '#')
- ThrowException( "Unknown reference format");
-
- Collada::MeshInstance instance;
- instance.mMeshOrController = url+1; // skipping the leading #
-
- if ( !mReader->isEmptyElement())
- {
- // read material associations. Ignore additional elements inbetween
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if ( IsElement( "instance_material"))
- {
- // read ID of the geometry subgroup and the target material
- int attrGroup = GetAttribute( "symbol");
- std::string group = mReader->getAttributeValue( attrGroup);
- int attrMaterial = GetAttribute( "target");
- const char* urlMat = mReader->getAttributeValue( attrMaterial);
- Collada::SemanticMappingTable s;
- if ( urlMat[0] == '#')
- urlMat++;
-
- s.mMatName = urlMat;
-
- // resolve further material details + THIS UGLY AND NASTY semantic mapping stuff
- if ( !mReader->isEmptyElement())
- ReadMaterialVertexInputBinding(s);
-
- // store the association
- instance.mMaterials[group] = s;
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if ( strcmp( mReader->getNodeName(), "instance_geometry") == 0
- || strcmp( mReader->getNodeName(), "instance_controller") == 0)
- break;
- }
- }
- }
-
- // store it
- pNode->mMeshes.push_back( instance);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the collada scene
-void ColladaParser::ReadScene()
-{
- if ( mReader->isEmptyElement())
- return;
-
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "instance_visual_scene"))
- {
- // should be the first and only occurence
- if ( mRootNode)
- ThrowException( "Invalid scene containing multiple root nodes");
-
- // read the url of the scene to instance. Should be of format "#some_name"
- int urlIndex = GetAttribute( "url");
- const char* url = mReader->getAttributeValue( urlIndex);
- if ( url[0] != '#')
- ThrowException( "Unknown reference format");
-
- // find the referred scene, skip the leading #
- NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1);
- if ( sit == mNodeLibrary.end())
- ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\".");
- mRootNode = sit->second;
- } else {
- SkipElement();
- }
- }
- else if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Aborts the file reading with an exception
-void ColladaParser::ThrowException( const std::string& pError) const
-{
- throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skips all data until the end node of the current element
-void ColladaParser::SkipElement()
-{
- // nothing to skip if it's an <element />
- if ( mReader->isEmptyElement())
- return;
-
- // reroute
- SkipElement( mReader->getNodeName());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skips all data until the end node of the given element
-void ColladaParser::SkipElement( const char* pElement)
-{
- // copy the current node's name because it'a pointer to the reader's internal buffer,
- // which is going to change with the upcoming parsing
- std::string element = pElement;
- while ( mReader->read())
- {
- if ( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- if ( mReader->getNodeName() == element)
- break;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for an opening element of the given name, throws an exception if not found
-void ColladaParser::TestOpening( const char* pName)
-{
- // read element start
- if ( !mReader->read())
- ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of \"%s\" element.") % pName));
- // whitespace in front is ok, just read again if found
- if ( mReader->getNodeType() == irr::io::EXN_TEXT)
- if ( !mReader->read())
- ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of \"%s\" element.") % pName));
-
- if ( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
- ThrowException( boost::str( boost::format( "Expected start of \"%s\" element.") % pName));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for the closing tag of the given element, throws an exception if not found
-void ColladaParser::TestClosing( const char* pName)
-{
- // read closing tag
- if ( !mReader->read())
- ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
- // whitespace in front is ok, just read again if found
- if ( mReader->getNodeType() == irr::io::EXN_TEXT)
- if ( !mReader->read())
- ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
-
- if ( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
- ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
-int ColladaParser::GetAttribute( const char* pAttr) const
-{
- int index = TestAttribute( pAttr);
- if ( index != -1)
- return index;
-
- // attribute not found -> throw an exception
- ThrowException( boost::str( boost::format( "Expected attribute \"%s\" at element \"%s\".") % pAttr % mReader->getNodeName()));
- return -1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found
-int ColladaParser::TestAttribute( const char* pAttr) const
-{
- for ( int a = 0; a < mReader->getAttributeCount(); a++)
- if ( strcmp( mReader->getAttributeName( a), pAttr) == 0)
- return a;
-
- return -1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace.
-const char* ColladaParser::GetTextContent()
-{
- const char* sz = TestTextContent();
- if (!sz) {
- ThrowException( "Invalid contents in element \"n\".");
- }
- return sz;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace.
-const char* ColladaParser::TestTextContent()
-{
- // present node should be the beginning of an element
- if ( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
- ThrowException( "Expected opening element");
-
- // read contents of the element
- if ( !mReader->read())
- ThrowException( "Unexpected end of file while reading n element.");
- if ( mReader->getNodeType() != irr::io::EXN_TEXT)
- return NULL;
-
- // skip leading whitespace
- const char* text = mReader->getNodeData();
- SkipSpacesAndLineEnd( &text);
-
- return text;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Calculates the resulting transformation fromm all the given transform steps
-aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform>& pTransforms) const
-{
- aiMatrix4x4 res;
-
- for ( std::vector<Transform>::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it)
- {
- const Transform& tf = *it;
- switch( tf.mType)
- {
- case TF_LOOKAT:
- {
- aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]);
- aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]);
- aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize();
- aiVector3D dir = aiVector3D( dstPos - pos).Normalize();
- aiVector3D right = (dir ^ up).Normalize();
-
- res *= aiMatrix4x4(
- right.x, up.x, -dir.x, pos.x,
- right.y, up.y, -dir.y, pos.y,
- right.z, up.z, -dir.z, pos.z,
- 0, 0, 0, 1);
- break;
- }
- case TF_ROTATE:
- {
- aiMatrix4x4 rot;
- float angle = tf.f[3] * float( AI_MATH_PI) / 180.0f;
- aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]);
- aiMatrix4x4::Rotation( angle, axis, rot);
- res *= rot;
- break;
- }
- case TF_TRANSLATE:
- {
- aiMatrix4x4 trans;
- aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans);
- res *= trans;
- break;
- }
- case TF_SCALE:
- {
- aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- res *= scale;
- break;
- }
- case TF_SKEW:
- // TODO: (thom)
- ai_assert( false);
- break;
- case TF_MATRIX:
- {
- aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7],
- tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]);
- res *= mat;
- break;
- }
- default:
- assert( false);
- break;
- }
- }
-
- return res;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Determines the input data type for the given semantic string
-Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& pSemantic)
-{
- if ( pSemantic == "POSITION")
- return IT_Position;
- else if ( pSemantic == "TEXCOORD")
- return IT_Texcoord;
- else if ( pSemantic == "NORMAL")
- return IT_Normal;
- else if ( pSemantic == "COLOR")
- return IT_Color;
- else if ( pSemantic == "VERTEX")
- return IT_Vertex;
- else if ( pSemantic == "BINORMAL" || pSemantic == "TEXBINORMAL")
- return IT_Bitangent;
- else if ( pSemantic == "TANGENT" || pSemantic == "TEXTANGENT")
- return IT_Tangent;
-
- DefaultLogger::get()->warn( boost::str( boost::format( "Unknown vertex input type \"%s\". Ignoring.") % pSemantic));
- return IT_Invalid;
-}
-
-#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
diff --git a/3rdparty/assimp/code/ColladaParser.h b/3rdparty/assimp/code/ColladaParser.h
deleted file mode 100644
index cba18474..00000000
--- a/3rdparty/assimp/code/ColladaParser.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file ColladaParser.h
- * @brief Defines the parser helper class for the collada loader
- */
-
-#ifndef AI_COLLADAPARSER_H_INC
-#define AI_COLLADAPARSER_H_INC
-
-#include "irrXMLWrapper.h"
-#include "ColladaHelper.h"
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------
-/** Parser helper class for the Collada loader.
- *
- * Does all the XML reading and builds internal data structures from it,
- * but leaves the resolving of all the references to the loader.
-*/
-class ColladaParser
-{
- friend class ColladaLoader;
-
-protected:
- /** Constructor from XML file */
- ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
-
- /** Destructor */
- ~ColladaParser();
-
- /** Reads the contents of the file */
- void ReadContents();
-
- /** Reads the structure of the file */
- void ReadStructure();
-
- /** Reads asset informations such as coordinate system informations and legal blah */
- void ReadAssetInfo();
-
- /** Reads the animation library */
- void ReadAnimationLibrary();
-
- /** Reads an animation into the given parent structure */
- void ReadAnimation( Collada::Animation* pParent);
-
- /** Reads an animation sampler into the given anim channel */
- void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
-
- /** Reads the skeleton controller library */
- void ReadControllerLibrary();
-
- /** Reads a controller into the given mesh structure */
- void ReadController( Collada::Controller& pController);
-
- /** Reads the joint definitions for the given controller */
- void ReadControllerJoints( Collada::Controller& pController);
-
- /** Reads the joint weights for the given controller */
- void ReadControllerWeights( Collada::Controller& pController);
-
- /** Reads the image library contents */
- void ReadImageLibrary();
-
- /** Reads an image entry into the given image */
- void ReadImage( Collada::Image& pImage);
-
- /** Reads the material library */
- void ReadMaterialLibrary();
-
- /** Reads a material entry into the given material */
- void ReadMaterial( Collada::Material& pMaterial);
-
- /** Reads the camera library */
- void ReadCameraLibrary();
-
- /** Reads a camera entry into the given camera */
- void ReadCamera( Collada::Camera& pCamera);
-
- /** Reads the light library */
- void ReadLightLibrary();
-
- /** Reads a light entry into the given light */
- void ReadLight( Collada::Light& pLight);
-
- /** Reads the effect library */
- void ReadEffectLibrary();
-
- /** Reads an effect entry into the given effect*/
- void ReadEffect( Collada::Effect& pEffect);
-
- /** Reads an COMMON effect profile */
- void ReadEffectProfileCommon( Collada::Effect& pEffect);
-
- /** Read sampler properties */
- void ReadSamplerProperties( Collada::Sampler& pSampler);
-
- /** Reads an effect entry containing a color or a texture defining that color */
- void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
-
- /** Reads an effect entry containing a float */
- void ReadEffectFloat( float& pFloat);
-
- /** Reads an effect parameter specification of any kind */
- void ReadEffectParam( Collada::EffectParam& pParam);
-
- /** Reads the geometry library contents */
- void ReadGeometryLibrary();
-
- /** Reads a geometry from the geometry library. */
- void ReadGeometry( Collada::Mesh* pMesh);
-
- /** Reads a mesh from the geometry library */
- void ReadMesh( Collada::Mesh* pMesh);
-
- /** Reads a source element - a combination of raw data and an accessor defining
- * things that should not be redefinable. Yes, that's another rant.
- */
- void ReadSource();
-
- /** Reads a data array holding a number of elements, and stores it in the global library.
- * Currently supported are array of floats and arrays of strings.
- */
- void ReadDataArray();
-
- /** Reads an accessor and stores it in the global library under the given ID -
- * accessors use the ID of the parent <source> element
- */
- void ReadAccessor( const std::string& pID);
-
- /** Reads input declarations of per-vertex mesh data into the given mesh */
- void ReadVertexData( Collada::Mesh* pMesh);
-
- /** Reads input declarations of per-index mesh data into the given mesh */
- void ReadIndexData( Collada::Mesh* pMesh);
-
- /** Reads a single input channel element and stores it in the given array, if valid */
- void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
-
- /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
- void ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
- size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
-
- /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
- void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
-
- /** Reads the library of node hierarchies and scene parts */
- void ReadSceneLibrary();
-
- /** Reads a scene node's contents including children and stores it in the given node */
- void ReadSceneNode( Collada::Node* pNode);
-
- /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
- void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
-
- /** Reads a mesh reference in a node and adds it to the node's mesh list */
- void ReadNodeGeometry( Collada::Node* pNode);
-
- /** Reads the collada scene */
- void ReadScene();
-
- // Processes bind_vertex_input and bind elements
- void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
-
-protected:
- /** Aborts the file reading with an exception */
- void ThrowException( const std::string& pError) const;
-
- /** Skips all data until the end node of the current element */
- void SkipElement();
-
- /** Skips all data until the end node of the given element */
- void SkipElement( const char* pElement);
-
- /** Compares the current xml element name to the given string and returns true if equal */
- bool IsElement( const char* pName) const;
-
- /** Tests for the opening tag of the given element, throws an exception if not found */
- void TestOpening( const char* pName);
-
- /** Tests for the closing tag of the given element, throws an exception if not found */
- void TestClosing( const char* pName);
-
- /** Checks the present element for the presence of the attribute, returns its index
- or throws an exception if not found */
- int GetAttribute( const char* pAttr) const;
-
- /** Returns the index of the named attribute or -1 if not found. Does not throw,
- therefore useful for optional attributes */
- int TestAttribute( const char* pAttr) const;
-
- /** Reads the text contents of an element, throws an exception if not given.
- Skips leading whitespace. */
- const char* GetTextContent();
-
- /** Reads the text contents of an element, returns NULL if not given.
- Skips leading whitespace. */
- const char* TestTextContent();
-
- /** Reads a single bool from current text content */
- bool ReadBoolFromTextContent();
-
- /** Reads a single float from current text content */
- float ReadFloatFromTextContent();
-
- /** Calculates the resulting transformation from all the given transform steps */
- aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
-
- /** Determines the input data type for the given semantic string */
- Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
-
- /** Finds the item in the given library by its reference, throws if not found */
- template <typename Type> const Type& ResolveLibraryReference(
- const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
-
-protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** XML reader, member for everyday use */
- irr::io::IrrXMLReader* mReader;
-
- /** All data arrays found in the file by ID. Might be referred to by actually
- everyone. Collada, you are a steaming pile of indirection. */
- typedef std::map<std::string, Collada::Data> DataLibrary;
- DataLibrary mDataLibrary;
-
- /** Same for accessors which define how the data in a data array is accessed. */
- typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
- AccessorLibrary mAccessorLibrary;
-
- /** Mesh library: mesh by ID */
- typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
- MeshLibrary mMeshLibrary;
-
- /** node library: root node of the hierarchy part by ID */
- typedef std::map<std::string, Collada::Node*> NodeLibrary;
- NodeLibrary mNodeLibrary;
-
- /** Image library: stores texture properties by ID */
- typedef std::map<std::string, Collada::Image> ImageLibrary;
- ImageLibrary mImageLibrary;
-
- /** Effect library: surface attributes by ID */
- typedef std::map<std::string, Collada::Effect> EffectLibrary;
- EffectLibrary mEffectLibrary;
-
- /** Material library: surface material by ID */
- typedef std::map<std::string, Collada::Material> MaterialLibrary;
- MaterialLibrary mMaterialLibrary;
-
- /** Light library: surface light by ID */
- typedef std::map<std::string, Collada::Light> LightLibrary;
- LightLibrary mLightLibrary;
-
- /** Camera library: surface material by ID */
- typedef std::map<std::string, Collada::Camera> CameraLibrary;
- CameraLibrary mCameraLibrary;
-
- /** Controller library: joint controllers by ID */
- typedef std::map<std::string, Collada::Controller> ControllerLibrary;
- ControllerLibrary mControllerLibrary;
-
- /** Pointer to the root node. Don't delete, it just points to one of
- the nodes in the node library. */
- Collada::Node* mRootNode;
-
- /** Root animation container */
- Collada::Animation mAnims;
-
- /** Size unit: how large compared to a meter */
- float mUnitSize;
-
- /** Which is the up vector */
- enum { UP_X, UP_Y, UP_Z } mUpDirection;
-
- /** Collada file format version */
- Collada::FormatVersion mFormat;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Check for element match
-inline bool ColladaParser::IsElement( const char* pName) const
-{
- ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
- return ::strcmp( mReader->getNodeName(), pName) == 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds the item in the given library by its reference, throws if not found
-template <typename Type>
-const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
-{
- typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
- if ( it == pLibrary.end())
- ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
- return it->second;
-}
-
-} // end of namespace Assimp
-
-#endif // AI_COLLADAPARSER_H_INC
diff --git a/3rdparty/assimp/code/ComputeUVMappingProcess.cpp b/3rdparty/assimp/code/ComputeUVMappingProcess.cpp
deleted file mode 100644
index 8fdbf69b..00000000
--- a/3rdparty/assimp/code/ComputeUVMappingProcess.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file GenUVCoords step */
-
-
-#include "AssimpPCH.h"
-#include "ComputeUVMappingProcess.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-namespace {
-
- const static aiVector3D base_axis_y(0.f,1.f,0.f);
- const static aiVector3D base_axis_x(1.f,0.f,0.f);
- const static aiVector3D base_axis_z(0.f,0.f,1.f);
- const static float angle_epsilon = 0.95f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ComputeUVMappingProcess::ComputeUVMappingProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ComputeUVMappingProcess::~ComputeUVMappingProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenUVCoords) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a ray intersects a plane and find the intersection point
-inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
- const aiVector3D& planeNormal, aiVector3D& pos)
-{
- const float b = planeNormal * (planePos - ray.pos);
- float h = ray.dir * planeNormal;
- if ((h < 10e-5f && h > -10e-5f) || (h = b/h) < 0)
- return false;
-
- pos = ray.pos + (ray.dir * h);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find the first empty UV channel in a mesh
-inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
-{
- for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
- if (!mesh->mTextureCoords[m])return m;
-
- DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
- return 0xffffffff;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to remove UV seams
-void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
-{
- // TODO: just a very rough algorithm. I think it could be done
- // much easier, but I don't know how and am currently too tired to
- // to think about a better solution.
-
- const static float LOWER_LIMIT = 0.1f;
- const static float UPPER_LIMIT = 0.9f;
-
- const static float LOWER_EPSILON = 10e-3f;
- const static float UPPER_EPSILON = 1.f-10e-3f;
-
- for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
- {
- const aiFace& face = mesh->mFaces[fidx];
- if (face.mNumIndices < 3) continue; // triangles and polygons only, please
-
- unsigned int small = face.mNumIndices, large = small;
- bool zero = false, one = false, round_to_zero = false;
-
- // Check whether this face lies on a UV seam. We can just guess,
- // but the assumption that a face with at least one very small
- // on the one side and one very large U coord on the other side
- // lies on a UV seam should work for most cases.
- for (unsigned int n = 0; n < face.mNumIndices;++n)
- {
- if (out[face.mIndices[n]].x < LOWER_LIMIT)
- {
- small = n;
-
- // If we have a U value very close to 0 we can't
- // round the others to 0, too.
- if (out[face.mIndices[n]].x <= LOWER_EPSILON)
- zero = true;
- else round_to_zero = true;
- }
- if (out[face.mIndices[n]].x > UPPER_LIMIT)
- {
- large = n;
-
- // If we have a U value very close to 1 we can't
- // round the others to 1, too.
- if (out[face.mIndices[n]].x >= UPPER_EPSILON)
- one = true;
- }
- }
- if (small != face.mNumIndices && large != face.mNumIndices)
- {
- for (unsigned int n = 0; n < face.mNumIndices;++n)
- {
- // If the u value is over the upper limit and no other u
- // value of that face is 0, round it to 0
- if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
- out[face.mIndices[n]].x = 0.f;
-
- // If the u value is below the lower limit and no other u
- // value of that face is 1, round it to 1
- else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one)
- out[face.mIndices[n]].x = 1.f;
-
- // The face contains both 0 and 1 as UV coords. This can occur
- // for faces which have an edge that lies directly on the seam.
- // Due to numerical inaccuracies one U coord becomes 0, the
- // other 1. But we do still have a third UV coord to determine
- // to which side we must round to.
- else if (one && zero)
- {
- if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
- out[face.mIndices[n]].x = 0.f;
- else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
- out[face.mIndices[n]].x = 1.f;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- aiVector3D center, min, max;
- FindMeshCenter(mesh, center, min, max);
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
-
- // For each point get a normalized projection vector in the sphere,
- // get its longitude and latitude and map them to their respective
- // UV axes. Problems occur around the poles ... unsolvable.
- //
- // The spherical coordinate system looks like this:
- // x = cos(lon)*cos(lat)
- // y = sin(lon)*cos(lat)
- // z = sin(lat)
- //
- // Thus we can derive:
- // lat = arcsin (z)
- // lon = arctan (y/x)
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- // ... just the same again
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- // ... just the same again
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
- out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
- }
- }
-
-
- // Now find and remove UV seams. A seam occurs if a face has a tcoord
- // close to zero on the one side, and a tcoord close to one on the
- // other side.
- RemoveUVSeams(mesh,out);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- aiVector3D center, min, max;
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const float diff = max.x - min.x;
-
- // If the main axis is 'z', the z coordinate of a point 'p' is mapped
- // directly to the texture V axis. The other axis is derived from
- // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
- // 'c' is the center point of the mesh.
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.x - min.x) / diff;
- uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const float diff = max.y - min.y;
-
- // just the same ...
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.y - min.y) / diff;
- uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const float diff = max.z - min.z;
-
- // just the same ...
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.z - min.z) / diff;
- uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
- FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
- const float diff = max.y - min.y;
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
- const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.y - min.y) / diff;
- uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
- }
- }
-
- // Now find and remove UV seams. A seam occurs if a face has a tcoord
- // close to zero on the one side, and a tcoord close to one on the
- // other side.
- RemoveUVSeams(mesh,out);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- float diffu,diffv;
- aiVector3D center, min, max;
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.z - min.z;
- diffv = max.y - min.y;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv);
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.x - min.x;
- diffv = max.z - min.z;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv);
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.y - min.y;
- diffv = max.z - min.z;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv);
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else
- {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
- FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
- diffu = max.x - min.x;
- diffv = max.z - min.z;
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
- out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv);
- }
- }
-
- // shouldn't be necessary to remove UV seams ...
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* /*mesh*/, aiVector3D* /*out*/)
-{
- DefaultLogger::get()->error("Mapping type currently not implemented");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenUVCoordsProcess begin");
- char buffer[1024];
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
-
- std::list<MappingInfo> mappingStack;
-
- /* Iterate through all materials and search for non-UV mapped textures
- */
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- mappingStack.clear();
- aiMaterial* mat = pScene->mMaterials[i];
- for (unsigned int a = 0; a < mat->mNumProperties;++a)
- {
- aiMaterialProperty* prop = mat->mProperties[a];
- if (!::strcmp( prop->mKey.data, "$tex.mapping"))
- {
- aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
- if (aiTextureMapping_UV != mapping)
- {
- if (!DefaultLogger::isNullLogger())
- {
- sprintf(buffer, "Found non-UV mapped texture (%s,%i). Mapping type: %s",
- TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
- MappingTypeToString(mapping));
-
- DefaultLogger::get()->info(buffer);
- }
-
- if (aiTextureMapping_OTHER == mapping)
- continue;
-
- MappingInfo info (mapping);
-
- // Get further properties - currently only the major axis
- for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
- {
- aiMaterialProperty* prop2 = mat->mProperties[a2];
- if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
- continue;
-
- if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) {
- info.axis = *((aiVector3D*)prop2->mData);
- break;
- }
- }
-
- unsigned int idx;
-
- // Check whether we have this mapping mode already
- std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
- if (mappingStack.end() != it)
- {
- idx = (*it).uv;
- }
- else
- {
- /* We have found a non-UV mapped texture. Now
- * we need to find all meshes using this material
- * that we can compute UV channels for them.
- */
- for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
- {
- aiMesh* mesh = pScene->mMeshes[m];
- unsigned int outIdx;
- if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == 0xffffffff ||
- !mesh->mNumVertices)
- {
- continue;
- }
-
- // Allocate output storage
- aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
-
- switch (mapping)
- {
- case aiTextureMapping_SPHERE:
- ComputeSphereMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_CYLINDER:
- ComputeCylinderMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_PLANE:
- ComputePlaneMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_BOX:
- ComputeBoxMapping(mesh,p);
- break;
- default:
- ai_assert(false);
- }
- if (m && idx != outIdx)
- {
- DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
- "this material have equal numbers of UV channels. The UV index stored in "
- "the material structure does therefore not apply for all meshes. ");
- }
- idx = outIdx;
- }
- info.uv = idx;
- mappingStack.push_back(info);
- }
-
- // Update the material property list
- mapping = aiTextureMapping_UV;
- ((MaterialHelper*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
- }
- }
- }
- }
- DefaultLogger::get()->debug("GenUVCoordsProcess finished");
-}
diff --git a/3rdparty/assimp/code/ComputeUVMappingProcess.h b/3rdparty/assimp/code/ComputeUVMappingProcess.h
deleted file mode 100644
index 795cc9fa..00000000
--- a/3rdparty/assimp/code/ComputeUVMappingProcess.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to compute UV coordinates
- from abstract mappings, such as box or spherical*/
-#ifndef AI_COMPUTEUVMAPPING_H_INC
-#define AI_COMPUTEUVMAPPING_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class ComputeUVMappingTest;
-namespace Assimp
- {
-
-// ---------------------------------------------------------------------------
-/** ComputeUVMappingProcess - converts special mappings, such as spherical,
- * cylindrical or boxed to proper UV coordinates for rendering.
-*/
-class ASSIMP_API ComputeUVMappingProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::ComputeUVMappingTest; // grant the unit test full access to us
-
-protected:
- /** Constructor to be privately used by Importer */
- ComputeUVMappingProcess();
-
- /** Destructor, private as well */
- ~ComputeUVMappingProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Computes spherical UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes cylindrical UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes planar UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes cubic UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param out Receives output UV coordinates
- */
- void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
-
-private:
-
- // temporary structure to describe a mapping
- struct MappingInfo
- {
- MappingInfo(aiTextureMapping _type)
- : type (_type)
- , axis (0.f,1.f,0.f)
- , uv (0u)
- {}
-
- aiTextureMapping type;
- aiVector3D axis;
- unsigned int uv;
-
- bool operator== (const MappingInfo& other)
- {
- return type == other.type && axis == other.axis;
- }
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_COMPUTEUVMAPPING_H_INC
diff --git a/3rdparty/assimp/code/ConvertToLHProcess.cpp b/3rdparty/assimp/code/ConvertToLHProcess.cpp
deleted file mode 100644
index d598ffd1..00000000
--- a/3rdparty/assimp/code/ConvertToLHProcess.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MakeLeftHandedProcess.cpp
- * @brief Implementation of the post processing step to convert all
- * imported data to a left-handed coordinate system.
- *
- * Face order & UV flip are also implemented here, for the sake of a
- * better location.
- */
-
-#include "AssimpPCH.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-
-#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MakeLeftHandedProcess::MakeLeftHandedProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MakeLeftHandedProcess::~MakeLeftHandedProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_MakeLeftHanded);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void MakeLeftHandedProcess::Execute( aiScene* pScene)
-{
- // Check for an existent root node to proceed
- ai_assert(pScene->mRootNode != NULL);
- DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
-
- // recursively convert all the nodes
- ProcessNode( pScene->mRootNode, aiMatrix4x4());
-
- // process the meshes accordingly
- for ( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
- ProcessMesh( pScene->mMeshes[a]);
-
- // process the materials accordingly
- for ( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
- ProcessMaterial( pScene->mMaterials[a]);
-
- // transform all animation channels as well
- for ( unsigned int a = 0; a < pScene->mNumAnimations; a++)
- {
- aiAnimation* anim = pScene->mAnimations[a];
- for ( unsigned int b = 0; b < anim->mNumChannels; b++)
- {
- aiNodeAnim* nodeAnim = anim->mChannels[b];
- ProcessAnimation( nodeAnim);
- }
- }
- DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively converts a node, all of its children and all of its meshes
-void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
-{
- // mirror all base vectors at the local Z axis
- pNode->mTransformation.c1 = -pNode->mTransformation.c1;
- pNode->mTransformation.c2 = -pNode->mTransformation.c2;
- pNode->mTransformation.c3 = -pNode->mTransformation.c3;
- pNode->mTransformation.c4 = -pNode->mTransformation.c4;
-
- // now invert the Z axis again to keep the matrix determinant positive.
- // The local meshes will be inverted accordingly so that the result should look just fine again.
- pNode->mTransformation.a3 = -pNode->mTransformation.a3;
- pNode->mTransformation.b3 = -pNode->mTransformation.b3;
- pNode->mTransformation.c3 = -pNode->mTransformation.c3;
- pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
-
- // continue for all children
- for ( size_t a = 0; a < pNode->mNumChildren; ++a)
- ProcessNode( pNode->mChildren[a], pParentGlobalRotation * pNode->mTransformation);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
-{
- // mirror positions, normals and stuff along the Z axis
- for ( size_t a = 0; a < pMesh->mNumVertices; ++a)
- {
- pMesh->mVertices[a].z *= -1.0f;
- if ( pMesh->HasNormals())
- pMesh->mNormals[a].z *= -1.0f;
- if ( pMesh->HasTangentsAndBitangents())
- {
- pMesh->mTangents[a].z *= -1.0f;
- pMesh->mBitangents[a].z *= -1.0f;
- }
- }
-
- // mirror offset matrices of all bones
- for ( size_t a = 0; a < pMesh->mNumBones; ++a)
- {
- aiBone* bone = pMesh->mBones[a];
- bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
- bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
- bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
- bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
- bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
- bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
- }
-
- // mirror bitangents as well as they're derived from the texture coords
- if ( pMesh->HasTangentsAndBitangents())
- {
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- pMesh->mBitangents[a] *= -1.0f;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single material to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
-{
- MaterialHelper* mat = (MaterialHelper*)_mat;
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
- aiMaterialProperty* prop = mat->mProperties[a];
-
- // Mapping axis for UV mappings?
- if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
- ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
- aiVector3D* pff = (aiVector3D*)prop->mData;
-
- pff->z *= -1.f;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the given animation to LH coordinates.
-void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
-{
- // position keys
- for ( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
- pAnim->mPositionKeys[a].mValue.z *= -1.0f;
-
- // rotation keys
- for ( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
- {
- /* That's the safe version, but the float errors add up. So we try the short version instead
- aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
- rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
- rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
- aiQuaternion rotquat( rotmat);
- pAnim->mRotationKeys[a].mValue = rotquat;
- */
- pAnim->mRotationKeys[a].mValue.x *= -1.0f;
- pAnim->mRotationKeys[a].mValue.y *= -1.0f;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
-#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
-// # FlipUVsProcess
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FlipUVsProcess::FlipUVsProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FlipUVsProcess::~FlipUVsProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FlipUVsProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FlipUVs);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FlipUVsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FlipUVsProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- ProcessMesh(pScene->mMeshes[i]);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- ProcessMaterial(pScene->mMaterials[i]);
- DefaultLogger::get()->debug("FlipUVsProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single material
-void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
-{
- MaterialHelper* mat = (MaterialHelper*)_mat;
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
- aiMaterialProperty* prop = mat->mProperties[a];
-
- // UV transformation key?
- if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
- ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
- aiUVTransform* uv = (aiUVTransform*)prop->mData;
-
- // just flip it, that's everything
- uv->mTranslation.y *= -1.f;
- uv->mRotation *= -1.f;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh
-void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
-{
- // mirror texture y coordinate
- for ( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
- if ( !pMesh->HasTextureCoords( a))
- break;
-
- for ( unsigned int b = 0; b < pMesh->mNumVertices; b++)
- pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
- }
-}
-
-#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
-#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
-// # FlipWindingOrderProcess
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FlipWindingOrderProcess::FlipWindingOrderProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FlipWindingOrderProcess::~FlipWindingOrderProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FlipWindingOrder);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FlipWindingOrderProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- ProcessMesh(pScene->mMeshes[i]);
- DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh
-void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
-{
- // invert the order of all faces in this mesh
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- aiFace& face = pMesh->mFaces[a];
- for ( unsigned int b = 0; b < face.mNumIndices / 2; b++)
- std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
diff --git a/3rdparty/assimp/code/ConvertToLHProcess.h b/3rdparty/assimp/code/ConvertToLHProcess.h
deleted file mode 100644
index f953c39a..00000000
--- a/3rdparty/assimp/code/ConvertToLHProcess.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MakeLeftHandedProcess.h
- * @brief Defines a bunch of post-processing steps to handle
- * coordinate system conversions.
- *
- * - LH to RH
- * - UV origin upper-left to lower-left
- * - face order cw to ccw
- */
-#ifndef AI_CONVERTTOLHPROCESS_H_INC
-#define AI_CONVERTTOLHPROCESS_H_INC
-
-#include "../include/aiTypes.h"
-#include "BaseProcess.h"
-
-struct aiMesh;
-struct aiNodeAnim;
-
-namespace Assimp {
-
-// -----------------------------------------------------------------------------------
-/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
- * coordinate system.
- *
- * This implies a mirroring of the Z axis of the coordinate system. But to keep
- * transformation matrices free from reflections we shift the reflection to other
- * places. We mirror the meshes and adapt the rotations.
- *
- * @note RH-LH and LH-RH is the same, so this class can be used for both
- */
-class ASSIMP_API MakeLeftHandedProcess : public BaseProcess
-{
- friend class Importer;
-
-public:
- /** Constructor to be privately used by Importer */
- MakeLeftHandedProcess();
-
- /** Destructor, private as well */
- ~MakeLeftHandedProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Recursively converts a node and all of its children
- */
- void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
-
- // -------------------------------------------------------------------
- /** Converts a single mesh to left handed coordinates.
- * This means that positions, normals and tangents are mirrored at
- * the local Z axis and the order of all faces are inverted.
- * @param pMesh The mesh to convert.
- */
- void ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Converts a single material to left-handed coordinates
- * @param pMat Material to convert
- */
- void ProcessMaterial( aiMaterial* pMat);
-
- // -------------------------------------------------------------------
- /** Converts the given animation to LH coordinates.
- * The rotation and translation keys are transformed, the scale keys
- * work in local space and can therefore be left untouched.
- * @param pAnim The bone animation to transform
- */
- void ProcessAnimation( aiNodeAnim* pAnim);
-};
-
-
-// ---------------------------------------------------------------------------
-/** Postprocessing step to flip the face order of the imported data
- */
-class ASSIMP_API FlipWindingOrderProcess : public BaseProcess
-{
- friend class Importer;
-
-public:
- /** Constructor to be privately used by Importer */
- FlipWindingOrderProcess();
-
- /** Destructor, private as well */
- ~FlipWindingOrderProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
- void ProcessMesh( aiMesh* pMesh);
-};
-
-// ---------------------------------------------------------------------------
-/** Postprocessing step to flip the UV coordinate system of the import data
- */
-class ASSIMP_API FlipUVsProcess : public BaseProcess
-{
- friend class Importer;
-
-public:
- /** Constructor to be privately used by Importer */
- FlipUVsProcess();
-
- /** Destructor, private as well */
- ~FlipUVsProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
- void ProcessMesh( aiMesh* pMesh);
- void ProcessMaterial( aiMaterial* mat);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CONVERTTOLHPROCESS_H_INC
diff --git a/3rdparty/assimp/code/DXFLoader.cpp b/3rdparty/assimp/code/DXFLoader.cpp
deleted file mode 100644
index 27ed471f..00000000
--- a/3rdparty/assimp/code/DXFLoader.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file DXFLoader.cpp
- * @brief Implementation of the DXF importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-
-#include "DXFLoader.h"
-#include "ParsingUtils.h"
-#include "ConvertToLHProcess.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-// AutoCAD Binary DXF<CR><LF><SUB><NULL>
-#define AI_DXF_BINARY_IDENT ("AutoCAD Binary DXF\r\n\x1a\0")
-#define AI_DXF_BINARY_IDENT_LEN (24)
-
-// color indices for DXF - 16 are supported
-static aiColor4D g_aclrDxfIndexColors[] =
-{
- aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
- aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
- aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
- aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
- aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
- aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
- aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
- aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
- aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
- aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
- aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
- aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
- aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
- aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
- aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
- aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
-};
-#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
-
-// invalid/unassigned color value
-aiColor4D g_clrInvalid = aiColor4D(get_qnan(),0.f,0.f,1.f);
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-DXFImporter::DXFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DXFImporter::~DXFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"dxf");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported file extensions
-void DXFImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("dxf");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a copy of the next data line, skip strange data
-bool DXFImporter::GetNextLine()
-{
- if (!SkipLine(&buffer))
- return false;
- if (!SkipSpaces(&buffer))
- return GetNextLine();
- else if (*buffer == '{') {
- // some strange meta data ...
- while (true)
- {
- if (!SkipLine(&buffer))
- return false;
-
- if (SkipSpaces(&buffer) && *buffer == '}')
- break;
- }
- return GetNextLine();
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the next token in the file
-bool DXFImporter::GetNextToken()
-{
- if (bRepeat) {
- bRepeat = false;
- return true;
- }
-
- SkipSpaces(&buffer);
- groupCode = strtol10s(buffer,&buffer);
- if (!GetNextLine())
- return false;
-
- // copy the data line to a separate buffer
- char* m = cursor, *end = &cursor[4096];
- while (!IsSpaceOrNewLine( *buffer ) && m < end)
- *m++ = *buffer++;
-
- *m = '\0';
- GetNextLine();
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void DXFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open DXF file " + pFile + "");
- }
-
- // read the contents of the file in a buffer
- std::vector<char> buffer2;
- TextFileToBuffer(file.get(),buffer2);
- buffer = &buffer2[0];
-
- bRepeat = false;
- mDefaultLayer = NULL;
-
- // check whether this is a binaray DXF file - we can't read binary DXF files :-(
- if (!strncmp(AI_DXF_BINARY_IDENT,buffer,AI_DXF_BINARY_IDENT_LEN))
- throw DeadlyImportError("DXF: Binary files are not supported at the moment");
-
- // now get all lines of the file
- while (GetNextToken()) {
-
- if (2 == groupCode) {
-
- // ENTITIES and BLOCKS sections - skip the whole rest, no need to waste our time with them
- if (!::strcmp(cursor,"ENTITIES") || !::strcmp(cursor,"BLOCKS")) {
- if (!ParseEntities())
- break;
- else bRepeat = true;
- }
-
- // other sections - skip them to make sure there will be no name conflicts
- else {
- while ( GetNextToken()) {
- if (!::strcmp(cursor,"ENDSEC"))
- break;
- }
- }
- }
- // print comment strings
- else if (999 == groupCode) {
- DefaultLogger::get()->info(std::string( cursor ));
- }
- else if (!groupCode && !::strcmp(cursor,"EOF"))
- break;
- }
-
- // find out how many valud layers we have
- for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end(); it != end;++it) {
- if (!(*it).vPositions.empty())
- ++pScene->mNumMeshes;
- }
-
- if (!pScene->mNumMeshes)
- throw DeadlyImportError("DXF: this file contains no 3d data");
-
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
- unsigned int m = 0;
- for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();it != end;++it) {
- if ((*it).vPositions.empty()) {
- continue;
- }
- // generate the output mesh
- aiMesh* pMesh = pScene->mMeshes[m++] = new aiMesh();
- const std::vector<aiVector3D>& vPositions = (*it).vPositions;
- const std::vector<aiColor4D>& vColors = (*it).vColors;
-
- // check whether we need vertex colors here
- aiColor4D* clrOut = NULL;
- const aiColor4D* clr = NULL;
- for (std::vector<aiColor4D>::const_iterator it2 = (*it).vColors.begin(), end2 = (*it).vColors.end();it2 != end2; ++it2) {
-
- if ((*it2).r == (*it2).r) /* qnan? */ {
- clrOut = pMesh->mColors[0] = new aiColor4D[vPositions.size()];
- for (unsigned int i = 0; i < vPositions.size();++i)
- clrOut[i] = aiColor4D(0.6f,0.6f,0.6f,1.0f);
-
- clr = &vColors[0];
- break;
- }
- }
-
- pMesh->mNumFaces = (unsigned int)vPositions.size() / 4u;
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
-
- aiVector3D* vpOut = pMesh->mVertices = new aiVector3D[vPositions.size()];
- const aiVector3D* vp = &vPositions[0];
-
- for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
- aiFace& face = pMesh->mFaces[i];
-
- // check whether we need four, three or two indices here
- if (vp[1] == vp[2]) {
- face.mNumIndices = 2;
- }
- else if (vp[3] == vp[2]) {
- face.mNumIndices = 3;
- }
- else face.mNumIndices = 4;
- face.mIndices = new unsigned int[face.mNumIndices];
-
- for (unsigned int a = 0; a < face.mNumIndices;++a) {
- *vpOut++ = vp[a];
- if (clr) {
- if (is_not_qnan( clr[a].r )) {
- *clrOut = clr[a];
- }
- ++clrOut;
- }
- face.mIndices[a] = pMesh->mNumVertices++;
- }
- vp += 4;
- }
- }
-
- // generate the output scene graph
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<DXF_ROOT>");
-
- if (1 == pScene->mNumMeshes) {
- pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
- for (m = 0; m < pScene->mRootNode->mNumChildren;++m) {
- aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
- p->mName.length = ::strlen( mLayers[m].name );
- strcpy(p->mName.data, mLayers[m].name);
-
- p->mMeshes = new unsigned int[p->mNumMeshes = 1];
- p->mMeshes[0] = m;
- p->mParent = pScene->mRootNode;
- }
- }
-
- // generate a default material
- MaterialHelper* pcMat = new MaterialHelper();
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- pcMat->AddProperty(&s, AI_MATKEY_NAME);
-
- aiColor4D clrDiffuse(0.6f,0.6f,0.6f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
-
- clrDiffuse = aiColor4D(1.0f,1.0f,1.0f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
-
- clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
-
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-
- // flip winding order to be ccw
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-
- // --- everything destructs automatically ---
-}
-
-// ------------------------------------------------------------------------------------------------
-bool DXFImporter::ParseEntities()
-{
- while (GetNextToken()) {
- if (!groupCode) {
- if (!::strcmp(cursor,"3DFACE") || !::strcmp(cursor,"LINE") || !::strcmp(cursor,"3DLINE")){
- //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
- Parse3DFace();
- bRepeat = true;
- }
- if (!::strcmp(cursor,"POLYLINE") || !::strcmp(cursor,"LWPOLYLINE")){
- ParsePolyLine();
- bRepeat = true;
- }
- if (!::strcmp(cursor,"ENDSEC")) {
- return true;
- }
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::SetLayer(LayerInfo*& out)
-{
- for (std::vector<LayerInfo>::iterator it = mLayers.begin(),end = mLayers.end();it != end;++it) {
- if (!::strcmp( (*it).name, cursor )) {
- out = &(*it);
- break;
- }
- }
- if (!out) {
- // we don't have this layer yet
- mLayers.push_back(LayerInfo());
- out = &mLayers.back();
- ::strcpy(out->name,cursor);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::SetDefaultLayer(LayerInfo*& out)
-{
- if (!mDefaultLayer) {
- mLayers.push_back(LayerInfo());
- mDefaultLayer = &mLayers.back();
- }
- out = mDefaultLayer;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool DXFImporter::ParsePolyLine()
-{
- bool ret = false;
- LayerInfo* out = NULL;
-
- std::vector<aiVector3D> positions;
- std::vector<aiColor4D> colors;
- std::vector<unsigned int> indices;
- unsigned int flags = 0;
-
- while (GetNextToken()) {
- switch (groupCode)
- {
- case 0:
- {
- if (!::strcmp(cursor,"VERTEX")) {
- aiVector3D v;aiColor4D clr(g_clrInvalid);
- unsigned int idx[4] = {0xffffffff,0xffffffff,0xffffffff,0xffffffff};
- ParsePolyLineVertex(v, clr, idx);
- if (0xffffffff == idx[0]) {
- positions.push_back(v);
- colors.push_back(clr);
- }
- else {
- // check whether we have a fourth coordinate
- if (0xffffffff == idx[3]) {
- idx[3] = idx[2];
- }
-
- indices.reserve(indices.size()+4);
- for (unsigned int m = 0; m < 4;++m)
- indices.push_back(idx[m]);
- }
- bRepeat = true;
- }
- else if (!::strcmp(cursor,"ENDSEQ")) {
- ret = true;
- }
- break;
- }
-
- // flags --- important that we know whether it is a polyface mesh
- case 70:
- {
- if (!flags) {
- flags = strtol10(cursor);
- }
- break;
- };
-
- // optional number of vertices
- case 71:
- {
- positions.reserve(strtol10(cursor));
- break;
- }
-
- // optional number of faces
- case 72:
- {
- indices.reserve(strtol10(cursor));
- break;
- }
-
- // 8 specifies the layer
- case 8:
- {
- SetLayer(out);
- break;
- }
- }
- }
- if (!(flags & 64)) {
- DefaultLogger::get()->warn("DXF: Only polyface meshes are currently supported");
- return ret;
- }
-
- if (positions.size() < 3 || indices.size() < 3) {
- DefaultLogger::get()->warn("DXF: Unable to parse POLYLINE element - not enough vertices");
- return ret;
- }
-
- // use a default layer if necessary
- if (!out) {
- SetDefaultLayer(out);
- }
-
- flags = (unsigned int)(out->vPositions.size()+indices.size());
- out->vPositions.reserve(flags);
- out->vColors.reserve(flags);
-
- // generate unique vertices
- for (std::vector<unsigned int>::const_iterator it = indices.begin(), end = indices.end();it != end; ++it) {
- unsigned int idx = *it;
- if (idx > positions.size() || !idx) {
- DefaultLogger::get()->error("DXF: Polyface mesh index os out of range");
- idx = (unsigned int) positions.size();
- }
- out->vPositions.push_back(positions[idx-1]); // indices are one-based.
- out->vColors.push_back(colors[idx-1]); // indices are one-based.
- }
-
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool DXFImporter::ParsePolyLineVertex(aiVector3D& out,aiColor4D& clr, unsigned int* outIdx)
-{
- bool ret = false;
- while (GetNextToken()) {
- switch (groupCode)
- {
- case 0: ret = true;
- break;
-
- // todo - handle the correct layer for the vertex. At the moment it is assumed that all vertices of
- // a polyline are placed on the same global layer.
-
- // x position of the first corner
- case 10: out.x = fast_atof(cursor);break;
-
- // y position of the first corner
- case 20: out.y = -fast_atof(cursor);break;
-
- // z position of the first corner
- case 30: out.z = fast_atof(cursor);break;
-
- // POLYFACE vertex indices
- case 71: outIdx[0] = strtol10(cursor);break;
- case 72: outIdx[1] = strtol10(cursor);break;
- case 73: outIdx[2] = strtol10(cursor);break;
- // case 74: outIdx[3] = strtol10(cursor);break;
-
- // color
- case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break;
- };
- if (ret) {
- break;
- }
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool DXFImporter::Parse3DFace()
-{
- bool ret = false;
- LayerInfo* out = NULL;
-
- aiVector3D vip[4]; // -- vectors are initialized to zero
- aiColor4D clr(g_clrInvalid);
-
- // this is also used for for parsing line entities
- bool bThird = false;
-
- while (GetNextToken()) {
- switch (groupCode) {
- case 0:
- ret = true;
- break;
-
- // 8 specifies the layer
- case 8: {
- SetLayer(out);
- break;
- }
-
- // x position of the first corner
- case 10: vip[0].x = fast_atof(cursor);break;
-
- // y position of the first corner
- case 20: vip[0].y = -fast_atof(cursor);break;
-
- // z position of the first corner
- case 30: vip[0].z = fast_atof(cursor);break;
-
- // x position of the second corner
- case 11: vip[1].x = fast_atof(cursor);break;
-
- // y position of the second corner
- case 21: vip[1].y = -fast_atof(cursor);break;
-
- // z position of the second corner
- case 31: vip[1].z = fast_atof(cursor);break;
-
- // x position of the third corner
- case 12: vip[2].x = fast_atof(cursor);
- bThird = true;break;
-
- // y position of the third corner
- case 22: vip[2].y = -fast_atof(cursor);
- bThird = true;break;
-
- // z position of the third corner
- case 32: vip[2].z = fast_atof(cursor);
- bThird = true;break;
-
- // x position of the fourth corner
- case 13: vip[3].x = fast_atof(cursor);
- bThird = true;break;
-
- // y position of the fourth corner
- case 23: vip[3].y = -fast_atof(cursor);
- bThird = true;break;
-
- // z position of the fourth corner
- case 33: vip[3].z = fast_atof(cursor);
- bThird = true;break;
-
- // color
- case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break;
- };
- if (ret)
- break;
- }
-
- if (!bThird)
- vip[2] = vip[1];
-
- // use a default layer if necessary
- if (!out) {
- SetDefaultLayer(out);
- }
- // add the faces to the face list for this layer
- out->vPositions.push_back(vip[0]);
- out->vPositions.push_back(vip[1]);
- out->vPositions.push_back(vip[2]);
- out->vPositions.push_back(vip[3]); // might be equal to the third
-
- for (unsigned int i = 0; i < 4;++i)
- out->vColors.push_back(clr);
- return ret;
-}
-
-#endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER
-
diff --git a/3rdparty/assimp/code/DXFLoader.h b/3rdparty/assimp/code/DXFLoader.h
deleted file mode 100644
index 88b47ad3..00000000
--- a/3rdparty/assimp/code/DXFLoader.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file DXFLoader.h
- * @brief Declaration of the .dxf importer class.
- */
-#ifndef AI_DXFLOADER_H_INCLUDED
-#define AI_DXFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** DXF importer class
-*/
-class DXFImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- DXFImporter();
-
- /** Destructor, private as well */
- ~DXFImporter();
-
-
- // describes a single layer in the DXF file
- struct LayerInfo
- {
- LayerInfo()
- {
- name[0] = '\0';
- }
-
- char name[4096];
-
- // face buffer - order is x,y,z v1,v2,v3,v4
- // if v2 = v3: line
- // elsif v3 = v2: triangle
- // else: polygon
- std::vector<aiVector3D> vPositions;
- std::vector<aiColor4D> vColors;
- };
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Get the next line from the file.
- * @return false if the end of the file was reached
- */
- bool GetNextLine();
-
- // -------------------------------------------------------------------
- /** Get the next token (group code + data line) from the file.
- * @return false if the end of the file was reached
- */
- bool GetNextToken();
-
- // -------------------------------------------------------------------
- /** Parses the ENTITIES section in the file
- * @return false if the end of the file was reached
- */
- bool ParseEntities();
-
- // -------------------------------------------------------------------
- /** Parses a 3DFACE section in the file
- * @return false if the end of the file was reached
- */
- bool Parse3DFace();
-
- // -------------------------------------------------------------------
- /** Parses a POLYLINE section in the file
- * @return false if the end of the file was reached
- */
- bool ParsePolyLine();
-
- // -------------------------------------------------------------------
- /** Sets the current layer - cursor must point to the name of it.
- * @param out Receives a handle to the layer
- */
- void SetLayer(LayerInfo*& out);
-
- // -------------------------------------------------------------------
- /** Creates a default layer.
- * @param out Receives a handle to the default layer
- */
- void SetDefaultLayer(LayerInfo*& out);
-
- // -------------------------------------------------------------------
- /** Parses a VERTEX element in a POLYLINE/POLYFACE
- * @param out Receives the output vertex.
- * @param clr Receives the output vertex color - won't be modified
- * if it is not existing.
- * @param outIdx Receives the output vertex indices, if present.
- * Wont't be modified otherwise. Size must be at least 4.
- * @return false if the end of the file was reached
- */
- bool ParsePolyLineVertex(aiVector3D& out, aiColor4D& clr,
- unsigned int* outIdx);
-
-private:
-
- // points to the next section
- const char* buffer;
-
- // specifies the current group code
- int groupCode;
-
- // contains the current data line
- char cursor[4096];
-
- // specifies whether the next call to GetNextToken()
- // should return the current token a second time
- bool bRepeat;
-
- // list of all loaded layers
- std::vector<LayerInfo> mLayers;
- LayerInfo* mDefaultLayer;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/DefaultIOStream.cpp b/3rdparty/assimp/code/DefaultIOStream.cpp
deleted file mode 100644
index f68ad384..00000000
--- a/3rdparty/assimp/code/DefaultIOStream.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file DefaultIOStream.cpp
- * @brief Default File I/O implementation for #Importer
- */
-
-#include "AssimpPCH.h"
-
-#include "DefaultIOStream.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-using namespace Assimp;
-
-// ----------------------------------------------------------------------------------
-DefaultIOStream::~DefaultIOStream()
-{
- if (mFile) {
- ::fclose(mFile);
- }
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Read(void* pvBuffer,
- size_t pSize,
- size_t pCount)
-{
- ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
- return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount)
-{
- ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
- return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
-}
-
-// ----------------------------------------------------------------------------------
-aiReturn DefaultIOStream::Seek(size_t pOffset,
- aiOrigin pOrigin)
-{
- if (!mFile) {
- return AI_FAILURE;
- }
-
- // Just to check whether our enum maps one to one with the CRT constants
- BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR &&
- aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
-
- // do the seek
- return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Tell() const
-{
- if (!mFile) {
- return 0;
- }
- return ::ftell(mFile);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::FileSize() const
-{
- if (! mFile || mFilename.empty()) {
- return 0;
- }
-
- if (0xffffffff == cachedSize) {
-
- // TODO: Is that really faster if we're already owning a handle to the file?
-#if defined _WIN32 && !defined __GNUC__
- struct __stat64 fileStat;
- int err = _stat64( mFilename.c_str(), &fileStat );
- if (0 != err)
- return 0;
- cachedSize = (size_t) (fileStat.st_size);
-#else
- struct stat fileStat;
- int err = stat(mFilename.c_str(), &fileStat );
- if (0 != err)
- return 0;
- cachedSize = (size_t) (fileStat.st_size);
-#endif
- }
- return cachedSize;
-}
-
-// ----------------------------------------------------------------------------------
-void DefaultIOStream::Flush()
-{
- if (mFile) {
- ::fflush(mFile);
- }
-}
-
-// ----------------------------------------------------------------------------------
diff --git a/3rdparty/assimp/code/DefaultIOStream.h b/3rdparty/assimp/code/DefaultIOStream.h
deleted file mode 100644
index fef7565f..00000000
--- a/3rdparty/assimp/code/DefaultIOStream.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Default file I/O using fXXX()-family of functions */
-#ifndef AI_DEFAULTIOSTREAM_H_INC
-#define AI_DEFAULTIOSTREAM_H_INC
-
-#include <stdio.h>
-#include "../include/IOStream.h"
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-//! @class DefaultIOStream
-//! @brief Default IO implementation, use standard IO operations
-//! @note An instance of this class can exist without a valid file handle
-//! attached to it. All calls fail, but the instance can nevertheless be
-//! used with no restrictions.
-class DefaultIOStream : public IOStream
-{
- friend class DefaultIOSystem;
-
-protected:
- DefaultIOStream ();
- DefaultIOStream (FILE* pFile, const std::string &strFilename);
-
-public:
- /** Destructor public to allow simple deletion to close the file. */
- ~DefaultIOStream ();
-
- // -------------------------------------------------------------------
- // Read from stream
- size_t Read(void* pvBuffer,
- size_t pSize,
- size_t pCount);
-
-
- // -------------------------------------------------------------------
- // Write to stream
- size_t Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount);
-
- // -------------------------------------------------------------------
- // Seek specific position
- aiReturn Seek(size_t pOffset,
- aiOrigin pOrigin);
-
- // -------------------------------------------------------------------
- // Get current seek position
- size_t Tell() const;
-
- // -------------------------------------------------------------------
- // Get size of file
- size_t FileSize() const;
-
- // -------------------------------------------------------------------
- // Flush file contents
- void Flush();
-
-private:
- //! File datastructure, using clib
- FILE* mFile;
- //! Filename
- std::string mFilename;
-
- //! Cached file size
- mutable size_t cachedSize;
-};
-
-
-// ----------------------------------------------------------------------------------
-inline DefaultIOStream::DefaultIOStream () :
- mFile (NULL),
- mFilename (""),
- cachedSize (0xffffffff)
-{
- // empty
-}
-
-
-// ----------------------------------------------------------------------------------
-inline DefaultIOStream::DefaultIOStream (FILE* pFile,
- const std::string &strFilename) :
- mFile(pFile),
- mFilename(strFilename),
- cachedSize (0xffffffff)
-{
- // empty
-}
-// ----------------------------------------------------------------------------------
-
-} // ns assimp
-
-#endif //!!AI_DEFAULTIOSTREAM_H_INC
-
diff --git a/3rdparty/assimp/code/DefaultIOSystem.cpp b/3rdparty/assimp/code/DefaultIOSystem.cpp
deleted file mode 100644
index 436caa82..00000000
--- a/3rdparty/assimp/code/DefaultIOSystem.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file Default implementation of IOSystem using the standard C file functions */
-
-#include "AssimpPCH.h"
-
-#include <stdlib.h>
-#include "DefaultIOSystem.h"
-#include "DefaultIOStream.h"
-
-#ifdef __unix__
-#include <sys/param.h>
-#include <stdlib.h>
-#endif
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-DefaultIOSystem::DefaultIOSystem()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-DefaultIOSystem::~DefaultIOSystem()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for the existence of a file at the given path.
-bool DefaultIOSystem::Exists( const char* pFile) const
-{
- FILE* file = ::fopen( pFile, "rb");
- if ( !file)
- return false;
-
- ::fclose( file);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Open a new file with a given path.
-IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
-{
- ai_assert(NULL != strFile);
- ai_assert(NULL != strMode);
-
- FILE* file = ::fopen( strFile, strMode);
- if ( NULL == file)
- return NULL;
-
- return new DefaultIOStream(file, (std::string) strFile);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Closes the given file and releases all resources associated with it.
-void DefaultIOSystem::Close( IOStream* pFile)
-{
- delete pFile;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the operation specific directory separator
-char DefaultIOSystem::getOsSeparator() const
-{
-#ifndef _WIN32
- return '/';
-#else
- return '\\';
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// IOSystem default implementation (ComparePaths isn't a pure virtual function)
-bool IOSystem::ComparePaths (const char* one, const char* second) const
-{
- return !ASSIMP_stricmp(one,second);
-}
-
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-# define PATHLIMIT PATH_MAX
-#else
-# define PATHLIMIT 4096
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Convert a relative path into an absolute path
-inline void MakeAbsolutePath (const char* in, char* _out)
-{
- ai_assert(in && _out);
- char* ret;
-#ifdef _WIN32
- ret = ::_fullpath(_out, in,PATHLIMIT);
-#else
- // use realpath
- ret = realpath(in, _out);
-#endif
- if (!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- DefaultLogger::get()->warn("Invalid path: "+std::string(in));
- strcpy(_out,in);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// DefaultIOSystem's more specialized implementation
-bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
-{
- // chances are quite good both paths are formatted identically,
- // so we can hopefully return here already
- if ( !ASSIMP_stricmp(one,second) )
- return true;
-
- char temp1[PATHLIMIT];
- char temp2[PATHLIMIT];
-
- MakeAbsolutePath (one, temp1);
- MakeAbsolutePath (second, temp2);
-
- return !ASSIMP_stricmp(temp1,temp2);
-}
-
-#undef PATHLIMIT
diff --git a/3rdparty/assimp/code/DefaultIOSystem.h b/3rdparty/assimp/code/DefaultIOSystem.h
deleted file mode 100644
index ef481b3c..00000000
--- a/3rdparty/assimp/code/DefaultIOSystem.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Default implementation of IOSystem using the standard C file functions */
-#ifndef AI_DEFAULTIOSYSTEM_H_INC
-#define AI_DEFAULTIOSYSTEM_H_INC
-
-#include "../include/IOSystem.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Default implementation of IOSystem using the standard C file functions */
-class DefaultIOSystem : public IOSystem
-{
-public:
- /** Constructor. */
- DefaultIOSystem();
-
- /** Destructor. */
- ~DefaultIOSystem();
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const;
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const;
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* pMode = "rb");
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* pFile);
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* one, const char* second) const;
-};
-
-} //!ns Assimp
-
-#endif //AI_DEFAULTIOSYSTEM_H_INC
diff --git a/3rdparty/assimp/code/DefaultLogger.cpp b/3rdparty/assimp/code/DefaultLogger.cpp
deleted file mode 100644
index 02ae0582..00000000
--- a/3rdparty/assimp/code/DefaultLogger.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file DefaultLogger.cpp
- * @brief Implementation of DefaultLogger (and Logger)
- */
-
-#include "AssimpPCH.h"
-#include "DefaultIOSystem.h"
-
-// Default log streams
-#include "Win32DebugLogStream.h"
-#include "StdOStreamLogStream.h"
-#include "FileLogStream.h"
-
-#ifndef ASSIMP_BUILD_SINGLETHREADED
-# include <boost/thread/thread.hpp>
-# include <boost/thread/mutex.hpp>
-
-boost::mutex loggerMutex;
-#endif
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-NullLogger DefaultLogger::s_pNullLogger;
-Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
-
-// ----------------------------------------------------------------------------------
-// Represents a logstream + its error severity
-struct LogStreamInfo
-{
- unsigned int m_uiErrorSeverity;
- LogStream *m_pStream;
-
- // Constructor
- LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
- m_uiErrorSeverity( uiErrorSev ),
- m_pStream( pStream )
- {
- // empty
- }
-
- // Destructor
- ~LogStreamInfo()
- {
- delete m_pStream;
- }
-};
-
-// ----------------------------------------------------------------------------------
-// Construct a default log stream
-LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
- const char* name /*= "AssimpLog.txt"*/,
- IOSystem* io /*= NULL*/)
-{
- switch (streams)
- {
- // This is a platform-specific feature
- case aiDefaultLogStream_DEBUGGER:
-#ifdef WIN32
- return new Win32DebugLogStream();
-#else
- return NULL;
-#endif
-
- // Platform-independent default streams
- case aiDefaultLogStream_STDERR:
- return new StdOStreamLogStream(std::cerr);
- case aiDefaultLogStream_STDOUT:
- return new StdOStreamLogStream(std::cout);
- case aiDefaultLogStream_FILE:
- return (name && *name ? new FileLogStream(name,io) : NULL);
- default:
- // We don't know this default log stream, so raise an assertion
- ai_assert(false);
-
- };
-
- // For compilers without dead code path detection
- return NULL;
-}
-
-// ----------------------------------------------------------------------------------
-// Creates the only singleton instance
-Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
- LogSeverity severity /*= NORMAL*/,
- unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
- IOSystem* io /*= NULL*/)
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- boost::mutex::scoped_lock lock(loggerMutex);
-#endif
-
- if (m_pLogger && !isNullLogger() )
- delete m_pLogger;
-
- m_pLogger = new DefaultLogger( severity );
-
- // Attach default log streams
- // Stream the log to the MSVC debugger?
- if (defStreams & aiDefaultLogStream_DEBUGGER)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
-
- // Stream the log to COUT?
- if (defStreams & aiDefaultLogStream_STDOUT)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
-
- // Stream the log to CERR?
- if (defStreams & aiDefaultLogStream_STDERR)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
-
- // Stream the log to a file
- if (defStreams & aiDefaultLogStream_FILE && name && *name)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
-
- return m_pLogger;
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::debug(const std::string &message) {
-
- // SECURITY FIX: otherwise it's easy to produce overruns ...
- if (message.length()>MAX_LOG_MESSAGE_LENGTH) {
- ai_assert(false);
- return;
- }
- return OnDebug(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::info(const std::string &message) {
-
- // SECURITY FIX: otherwise it's easy to produce overruns ...
- if (message.length()>MAX_LOG_MESSAGE_LENGTH) {
- ai_assert(false);
- return;
- }
- return OnInfo(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::warn(const std::string &message) {
-
- // SECURITY FIX: otherwise it's easy to produce overruns ...
- if (message.length()>MAX_LOG_MESSAGE_LENGTH) {
- ai_assert(false);
- return;
- }
- return OnWarn(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::error(const std::string &message) {
-
- // SECURITY FIX: otherwise it's easy to produce overruns ...
- if (message.length()>MAX_LOG_MESSAGE_LENGTH) {
- ai_assert(false);
- return;
- }
- return OnError(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-void DefaultLogger::set( Logger *logger )
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- boost::mutex::scoped_lock lock(loggerMutex);
-#endif
-
- if (!logger)logger = &s_pNullLogger;
- if (m_pLogger && !isNullLogger() )
- delete m_pLogger;
-
- DefaultLogger::m_pLogger = logger;
-}
-
-// ----------------------------------------------------------------------------------
-bool DefaultLogger::isNullLogger()
-{
- return m_pLogger == &s_pNullLogger;
-}
-
-// ----------------------------------------------------------------------------------
-// Singleton getter
-Logger *DefaultLogger::get()
-{
- return m_pLogger;
-}
-
-// ----------------------------------------------------------------------------------
-// Kills the only instance
-void DefaultLogger::kill()
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- boost::mutex::scoped_lock lock(loggerMutex);
-#endif
-
- if (m_pLogger == &s_pNullLogger)return;
- delete m_pLogger;
- m_pLogger = &s_pNullLogger;
-}
-
-// ----------------------------------------------------------------------------------
-// Debug message
-void DefaultLogger::OnDebug( const char* message )
-{
- if ( m_Severity == Logger::NORMAL )
- return;
-
- char msg[MAX_LOG_MESSAGE_LENGTH*2];
- ::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message );
-
- WriteToStreams( msg, Logger::DEBUGGING );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs an info
-void DefaultLogger::OnInfo( const char* message )
-{
- char msg[MAX_LOG_MESSAGE_LENGTH*2];
- ::sprintf(msg,"Info, T%i: %s", GetThreadID(), message );
-
- WriteToStreams( msg , Logger::INFO );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs a warning
-void DefaultLogger::OnWarn( const char* message )
-{
- char msg[MAX_LOG_MESSAGE_LENGTH*2];
- ::sprintf(msg,"Warn, T%i: %s", GetThreadID(), message );
-
- WriteToStreams( msg, Logger::WARN );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs an error
-void DefaultLogger::OnError( const char* message )
-{
- char msg[MAX_LOG_MESSAGE_LENGTH*2];
- ::sprintf(msg,"Error, T%i: %s", GetThreadID(), message );
-
- WriteToStreams( msg, Logger::ERR );
-}
-
-// ----------------------------------------------------------------------------------
-// Attachs a new stream
-bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
-{
- if (!pStream)
- return false;
-
- if (0 == severity) {
- severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
- }
-
- for ( StreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it )
- {
- if ( (*it)->m_pStream == pStream )
- {
- (*it)->m_uiErrorSeverity |= severity;
- return true;
- }
- }
-
- LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
- m_StreamArray.push_back( pInfo );
- return true;
-}
-
-// ----------------------------------------------------------------------------------
-// Detatch a stream
-bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
-{
- if (!pStream)
- return false;
-
- if (0 == severity) {
- severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
- }
-
- for ( StreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it )
- {
- if ( (*it)->m_pStream == pStream )
- {
- (*it)->m_uiErrorSeverity &= ~severity;
- if ( (*it)->m_uiErrorSeverity == 0 )
- {
- // don't delete the underlying stream 'cause the caller gains ownership again
- (**it).m_pStream = NULL;
- delete *it;
- m_StreamArray.erase( it );
- break;
- }
- return true;
- }
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------------
-// Constructor
-DefaultLogger::DefaultLogger(LogSeverity severity)
-
- : Logger ( severity )
- , noRepeatMsg (false)
- , lastLen( 0 )
-{
- lastMsg[0] = '\0';
-}
-
-// ----------------------------------------------------------------------------------
-// Destructor
-DefaultLogger::~DefaultLogger()
-{
- for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
- // also frees the underlying stream, we are its owner.
- delete *it;
- }
-}
-
-// ----------------------------------------------------------------------------------
-// Writes message to stream
-void DefaultLogger::WriteToStreams(const char *message,
- ErrorSeverity ErrorSev )
-{
- ai_assert(NULL != message);
-
- // Check whether this is a repeated message
- if (! ::strncmp( message,lastMsg, lastLen-1))
- {
- if (!noRepeatMsg)
- {
- noRepeatMsg = true;
- message = "Skipping one or more lines with the same contents\n";
- }
- else return;
- }
- else
- {
- // append a new-line character to the message to be printed
- lastLen = ::strlen(message);
- ::memcpy(lastMsg,message,lastLen+1);
- ::strcat(lastMsg+lastLen,"\n");
-
- message = lastMsg;
- noRepeatMsg = false;
- ++lastLen;
- }
- for ( ConstStreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it)
- {
- if ( ErrorSev & (*it)->m_uiErrorSeverity )
- (*it)->m_pStream->write( message);
- }
-}
-
-// ----------------------------------------------------------------------------------
-// Returns thread id, if not supported only a zero will be returned.
-unsigned int DefaultLogger::GetThreadID()
-{
- // fixme: we can get this value via boost::threads
-#ifdef WIN32
- return (unsigned int)::GetCurrentThreadId();
-#else
- return 0; // not supported
-#endif
-}
-
-// ----------------------------------------------------------------------------------
-
-} // !namespace Assimp
diff --git a/3rdparty/assimp/code/DefaultProgressHandler.h b/3rdparty/assimp/code/DefaultProgressHandler.h
deleted file mode 100644
index 852f54cb..00000000
--- a/3rdparty/assimp/code/DefaultProgressHandler.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file ProgressHandler.h
- * @brief Abstract base class 'ProgressHandler'.
- */
-#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
-#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
-
-#include "../include/ProgressHandler.h"
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------
-/** @brief Internal default implementation of the #ProgressHandler interface. */
-class ASSIMP_API DefaultProgressHandler
- : public ProgressHandler {
-
-
- virtual bool Update(float /*percentage*/) {
- return false;
- }
-
-
-}; // !class DefaultProgressHandler
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/Exceptional.h b/3rdparty/assimp/code/Exceptional.h
deleted file mode 100644
index e9f93186..00000000
--- a/3rdparty/assimp/code/Exceptional.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef INCLUDED_EXCEPTIONAL_H
-#define INCLUDED_EXCEPTIONAL_H
-
-#include <stdexcept>
-using std::runtime_error;
-
-#ifdef _MSC_VER
-# pragma warning(disable : 4275)
-#endif
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
- * unrecoverable error occurs while importing. Loading APIs return
- * NULL instead of a valid aiScene then. */
-class ASSIMP_API DeadlyImportError
- : public runtime_error
-{
-public:
- /** Constructor with arguments */
- explicit DeadlyImportError( const std::string& pErrorText)
- : runtime_error(pErrorText)
- {
- }
-
-private:
-};
-
-#ifdef _MSC_VER
-# pragma warning(default : 4275)
-#endif
-
-// ---------------------------------------------------------------------------
-template <typename T>
-struct ExceptionSwallower {
- T operator ()() const {
- return T();
- }
-};
-
-// ---------------------------------------------------------------------------
-template <typename T>
-struct ExceptionSwallower<T*> {
- T* operator ()() const {
- return NULL;
- }
-};
-
-// ---------------------------------------------------------------------------
-template <>
-struct ExceptionSwallower<aiReturn> {
- aiReturn operator ()() const {
- try {
- throw;
- }
- catch (std::bad_alloc&) {
- return aiReturn_OUTOFMEMORY;
- }
- catch (...) {
- return aiReturn_FAILURE;
- }
- }
-};
-
-// ---------------------------------------------------------------------------
-template <>
-struct ExceptionSwallower<void> {
- void operator ()() const {
- return;
- }
-};
-
-#define ASSIMP_BEGIN_EXCEPTION_REGION()\
-{\
- try {
-
-#define ASSIMP_END_EXCEPTION_REGION(type)\
- } catch(...) {\
- return ExceptionSwallower<type>()();\
- }\
-}
-
-#endif // INCLUDED_EXCEPTIONAL_H
diff --git a/3rdparty/assimp/code/FileLogStream.h b/3rdparty/assimp/code/FileLogStream.h
deleted file mode 100644
index 605ed509..00000000
--- a/3rdparty/assimp/code/FileLogStream.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef ASSIMP_FILELOGSTREAM_H_INC
-#define ASSIMP_FILELOGSTREAM_H_INC
-
-#include "../include/LogStream.h"
-#include "../include/IOStream.h"
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** @class FileLogStream
- * @brief Logstream to write into a file.
- */
-class FileLogStream :
- public LogStream
-{
-public:
- FileLogStream( const char* file, IOSystem* io = NULL );
- ~FileLogStream();
- void write( const char* message );
-
-private:
- IOStream *m_pStream;
-};
-
-// ----------------------------------------------------------------------------------
-// Constructor
-inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) :
- m_pStream(NULL)
-{
- if ( !file || 0 == *file )
- return;
-
- // If no IOSystem is specified: take a default one
- if (!io)
- {
- DefaultIOSystem FileSystem;
- m_pStream = FileSystem.Open( file, "wt");
- }
- else m_pStream = io->Open( file, "wt" );
-}
-
-// ----------------------------------------------------------------------------------
-// Destructor
-inline FileLogStream::~FileLogStream()
-{
- // The virtual d'tor should destroy the underlying file
- delete m_pStream;
-}
-
-// ----------------------------------------------------------------------------------
-// Write method
-inline void FileLogStream::write( const char* message )
-{
- if (m_pStream != NULL)
- {
- m_pStream->Write(message, sizeof(char), ::strlen(message));
- m_pStream->Flush();
- }
-}
-
-// ----------------------------------------------------------------------------------
-} // !Namespace Assimp
-
-#endif // !! ASSIMP_FILELOGSTREAM_H_INC
diff --git a/3rdparty/assimp/code/FileSystemFilter.h b/3rdparty/assimp/code/FileSystemFilter.h
deleted file mode 100644
index a23c8412..00000000
--- a/3rdparty/assimp/code/FileSystemFilter.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file FileSystemFilter.h
- * Implements a filter system to filter calls to Exists() and Open()
- * in order to improve the sucess rate of file opening ...
- */
-#ifndef AI_FILESYSTEMFILTER_H_INC
-#define AI_FILESYSTEMFILTER_H_INC
-
-#include "../include/IOSystem.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** File system filter
- */
-class FileSystemFilter : public IOSystem
-{
-public:
- /** Constructor. */
- FileSystemFilter(const std::string& file, IOSystem* old)
- : wrapped (old)
- , src_file (file)
- {
- ai_assert(NULL != wrapped);
-
- // Determine base directory
- base = src_file;
- std::string::size_type ss2;
- if (std::string::npos != (ss2 = base.find_last_of("\\/"))) {
- base.erase(ss2,base.length()-ss2);
- }
- else {
- base = "";
- // return;
- }
-
- // make sure the directory is terminated properly
- char s;
-
- if (base.length() == 0) {
- base = ".";
- base += getOsSeparator();
- }
- else if ((s = *(base.end()-1)) != '\\' && s != '/')
- base += getOsSeparator();
-
- DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
- }
-
- /** Destructor. */
- ~FileSystemFilter()
- {
- // haha
- }
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const
- {
- std::string tmp = pFile;
-
- // Currently this IOSystem is also used to open THE ONE FILE.
- if (tmp != src_file) {
- BuildPath(tmp);
- Cleanup(tmp);
- }
-
- return wrapped->Exists(tmp);
- }
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const
- {
- return wrapped->getOsSeparator();
- }
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* pMode = "rb")
- {
- ai_assert(pFile);
- ai_assert(pMode);
-
- // First try the unchanged path
- IOStream* s = wrapped->Open(pFile,pMode);
-
- if (!s) {
- std::string tmp = pFile;
-
- // Try to convert between absolute and relative paths
- BuildPath(tmp);
- s = wrapped->Open(tmp,pMode);
-
- if (!s) {
- // Finally, look for typical issues with paths
- // and try to correct them. This is our last
- // resort.
- Cleanup(tmp);
- s = wrapped->Open(tmp,pMode);
- }
- }
-
- return s;
- }
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* pFile)
- {
- return wrapped->Close(pFile);
- }
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* one, const char* second) const
- {
- return wrapped->ComparePaths (one,second);
- }
-
-private:
- IOSystem* wrapped;
- std::string src_file, base;
-
- // -------------------------------------------------------------------
- /** Build a valid path from a given relative or absolute path.
- */
- void BuildPath (std::string& in) const
- {
- // if we can already access the file, great.
- if (in.length() < 3 || wrapped->Exists(in.c_str())) {
- return;
- }
-
- // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows).
- if (in[1] != ':') {
-
- // append base path and try
- in = base + in;
- if (wrapped->Exists(in.c_str())) {
- return;
- }
- }
-
- // hopefully the underyling file system has another few tricks to access this file ...
- }
-
- // -------------------------------------------------------------------
- /** Cleanup the given path
- */
- void Cleanup (std::string& in) const
- {
- char last = 0;
-
- // Remove a very common issue when we're parsing file names: spaces at the
- // beginning of the path.
- std::string::iterator it = in.begin();
- while (IsSpaceOrNewLine( *it ))++it;
- if (it != in.begin())
- in.erase(in.begin(),it+1);
-
- const char sep = getOsSeparator();
- for (it = in.begin(); it != in.end(); ++it) {
- // Exclude :// and \\, which remain untouched.
- // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
- if ( !strncmp(&*it, "://", 3 )) {
- it += 3;
- continue;
- }
- if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) {
- it += 2;
- continue;
- }
-
- // Cleanup path delimiters
- if (*it == '/' || (*it) == '\\') {
- *it = sep;
-
- // And we're removing double delimiters, frequent issue with
- // incorrectly composited paths ...
- if (last == *it) {
- it = in.erase(it);
- --it;
- }
- }
- else if (*it == '%' && in.end() - it > 2) {
-
- // Hex sequence in URIs
- uint32_t tmp;
- if ( 0xffffffff != (tmp = HexOctetToDecimal(&*it))) {
- *it = (char)tmp;
- it = in.erase(it+1,it+2);
- --it;
- }
- }
-
- last = *it;
- }
- }
-};
-
-} //!ns Assimp
-
-#endif //AI_DEFAULTIOSYSTEM_H_INC
diff --git a/3rdparty/assimp/code/FindDegenerates.cpp b/3rdparty/assimp/code/FindDegenerates.cpp
deleted file mode 100644
index 3cdd325d..00000000
--- a/3rdparty/assimp/code/FindDegenerates.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file FindDegenerates.cpp
- * @brief Implementation of the FindDegenerates post-process step.
-*/
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "ProcessHelper.h"
-#include "FindDegenerates.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindDegeneratesProcess::FindDegeneratesProcess()
-: configRemoveDegenerates (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindDegeneratesProcess::~FindDegeneratesProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FindDegenerates);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
-{
- // Get the current value of AI_CONFIG_PP_FD_REMOVE
- configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindDegeneratesProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FindDegeneratesProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
- ExecuteOnMesh( pScene->mMeshes[i]);
- }
- DefaultLogger::get()->debug("FindDegeneratesProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported mesh
-void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
-{
- mesh->mPrimitiveTypes = 0;
-
- std::vector<bool> remove_me;
- if (configRemoveDegenerates)
- remove_me.resize(mesh->mNumFaces,false);
-
- unsigned int deg = 0, limit;
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
- {
- aiFace& face = mesh->mFaces[a];
- bool first = true;
-
- // check whether the face contains degenerated entries
- for (register unsigned int i = 0; i < face.mNumIndices; ++i)
- {
- // Polygons with more than 4 points are allowed to have double points, that is
- // simulating polygons with holes just with concave polygons. However,
- // double points may not come directly after another.
- limit = face.mNumIndices;
- if (face.mNumIndices > 4)
- limit = std::min(limit,i+2);
-
- for (register unsigned int t = i+1; t < limit; ++t)
- {
- if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
- {
- // we have found a matching vertex position
- // remove the corresponding index from the array
- --face.mNumIndices;--limit;
- for (unsigned int m = t; m < face.mNumIndices; ++m)
- {
- face.mIndices[m] = face.mIndices[m+1];
- }
- --t;
-
- // NOTE: we set the removed vertex index to an unique value
- // to make sure the developer gets notified when his
- // application attemps to access this data.
- face.mIndices[face.mNumIndices] = 0xdeadbeef;
-
- if (first)
- {
- ++deg;
- first = false;
- }
-
- if (configRemoveDegenerates) {
- remove_me[a] = true;
- goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
- }
- }
- }
- }
-
- // We need to update the primitive flags array of the mesh.
- switch (face.mNumIndices)
- {
- case 1u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- };
-evil_jump_outside:
- continue;
- }
-
- // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
- if (configRemoveDegenerates && deg) {
- unsigned int n = 0;
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
- {
- aiFace& face_src = mesh->mFaces[a];
- if (!remove_me[a]) {
- aiFace& face_dest = mesh->mFaces[n++];
-
- // Do a manual copy, keep the index array
- face_dest.mNumIndices = face_src.mNumIndices;
- face_dest.mIndices = face_src.mIndices;
-
- if (&face_src != &face_dest) {
- // clear source
- face_src.mNumIndices = 0;
- face_src.mIndices = NULL;
- }
- }
- else {
- // Otherwise delete it if we don't need this face
- delete[] face_src.mIndices;
- face_src.mIndices = NULL;
- face_src.mNumIndices = 0;
- }
- }
- // Just leave the rest of the array unreferenced, we don't care for now
- mesh->mNumFaces = n;
- if (!mesh->mNumFaces) {
- // WTF!?
- // OK ... for completeness and because I'm not yet tired,
- // let's write code that willl hopefully never be called
- // (famous last words)
-
- // OK ... bad idea.
- throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
- }
- }
-
- if (deg && !DefaultLogger::isNullLogger())
- {
- char s[64];
- ASSIMP_itoa10(s,deg);
- DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
- }
-}
diff --git a/3rdparty/assimp/code/FindDegenerates.h b/3rdparty/assimp/code/FindDegenerates.h
deleted file mode 100644
index a4417919..00000000
--- a/3rdparty/assimp/code/FindDegenerates.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to search all meshes for
- degenerated faces */
-#ifndef AI_FINDDEGENERATESPROCESS_H_INC
-#define AI_FINDDEGENERATESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class FindDegeneratesProcessTest;
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
-*/
-class ASSIMP_API FindDegeneratesProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::FindDegeneratesProcessTest; // grant the unit test full access to us
-
-protected:
- /** Constructor to be privately used by Importer */
- FindDegeneratesProcess();
-
- /** Destructor, private as well */
- ~FindDegeneratesProcess();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- // Execute step on a given mesh
- void ExecuteOnMesh( aiMesh* mesh);
-
-
- // -------------------------------------------------------------------
- /** @brief Enable the instant removal of degenerated primitives
- * @param d hm ... difficult to guess what this means, hu!?
- */
- void EnableInstantRemoval(bool d) {
- configRemoveDegenerates = d;
- }
-
- // -------------------------------------------------------------------
- /** @brief Check whether instant removal is currently enabled
- * @return ...
- */
- bool IsInstantRemoval() const {
- return configRemoveDegenerates;
- }
-
-private:
-
- //! Configuration option: remove degenerates faces immediately
- bool configRemoveDegenerates;
-};
-}
-
-#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
diff --git a/3rdparty/assimp/code/FindInstancesProcess.cpp b/3rdparty/assimp/code/FindInstancesProcess.cpp
deleted file mode 100644
index 537f2ea4..00000000
--- a/3rdparty/assimp/code/FindInstancesProcess.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file FindInstancesProcess.cpp
- * @brief Implementation of the aiProcess_FindInstances postprocessing step
-*/
-
-#include "AssimpPCH.h"
-#include "FindInstancesProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindInstancesProcess::FindInstancesProcess()
-: configSpeedFlag (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInstancesProcess::~FindInstancesProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindInstancesProcess::IsActive( unsigned int pFlags) const
-{
- // FindInstances makes absolutely no sense together with PreTransformVertices
- // fixme: spawn error message somewhere else?
- return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the step
-void FindInstancesProcess::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compare the bones of two meshes
-bool CompareBones(const aiMesh* orig, const aiMesh* inst)
-{
- for (unsigned int i = 0; i < orig->mNumBones;++i) {
- aiBone* aha = orig->mBones[i];
- aiBone* oha = inst->mBones[i];
-
- if (aha->mNumWeights != oha->mNumWeights ||
- aha->mOffsetMatrix != oha->mOffsetMatrix ||
- aha->mNumWeights != oha->mNumWeights) {
- return false;
- }
-
- // compare weight per weight ---
- for (unsigned int n = 0; n < aha->mNumWeights;++n) {
- if (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId ||
- (aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) {
- return false;
- }
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update mesh indices in the node graph
-void UpdateMeshIndices(aiNode* node, unsigned int* lookup)
-{
- for (unsigned int n = 0; n < node->mNumMeshes;++n)
- node->mMeshes[n] = lookup[node->mMeshes[n]];
-
- for (unsigned int n = 0; n < node->mNumChildren;++n)
- UpdateMeshIndices(node->mChildren[n],lookup);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindInstancesProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FindInstancesProcess begin");
- if (pScene->mNumMeshes) {
-
- // use a pseudo hash for all meshes in the scene to quickly find
- // the ones which are possibly equal. This step is executed early
- // in the pipeline, so we could, depending on the file format,
- // have several thousand small meshes. That's too much for a brute
- // everyone-against-everyone check involving up to 10 comparisons
- // each.
- boost::scoped_array<uint64_t> hashes (new uint64_t[pScene->mNumMeshes]);
- boost::scoped_array<unsigned int> remapping (new unsigned int[pScene->mNumMeshes]);
-
- unsigned int numMeshesOut = 0;
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
-
- aiMesh* inst = pScene->mMeshes[i];
- hashes[i] = GetMeshHash(inst);
-
- for (int a = i-1; a >= 0; --a) {
- if (hashes[i] == hashes[a])
- {
- aiMesh* orig = pScene->mMeshes[a];
- if (!orig)
- continue;
-
- // check for hash collision .. we needn't check
- // the vertex format, it *must* match due to the
- // (brilliant) construction of the hash
- if (orig->mNumBones != inst->mNumBones ||
- orig->mNumFaces != inst->mNumFaces ||
- orig->mNumVertices != inst->mNumVertices ||
- orig->mMaterialIndex != inst->mMaterialIndex ||
- orig->mPrimitiveTypes != inst->mPrimitiveTypes)
- continue;
-
- // up to now the meshes are equal. find an appropriate
- // epsilon to compare position differences against
- float epsilon = ComputePositionEpsilon(inst);
- epsilon *= epsilon;
-
- // now compare vertex positions, normals,
- // tangents and bitangents using this epsilon.
- if (orig->HasPositions()) {
- if (!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
- continue;
- }
- if (orig->HasNormals()) {
- if (!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon))
- continue;
- }
- if (orig->HasTangentsAndBitangents()) {
- if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) ||
- !CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon))
- continue;
- }
-
- // use a constant epsilon for colors and UV coordinates
- static const float uvEpsilon = 10e-4f;
-
- BOOST_STATIC_ASSERT(4 == AI_MAX_NUMBER_OF_COLOR_SETS);
-
- // as in JIV: manually unrolled as continue wouldn't work as desired in inner loops
- if (orig->mTextureCoords[0]) {
- if (!CompareArrays(orig->mTextureCoords[0],inst->mTextureCoords[0],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[1]) {
- if (!CompareArrays(orig->mTextureCoords[1],inst->mTextureCoords[1],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[2]) {
- if (!CompareArrays(orig->mTextureCoords[2],inst->mTextureCoords[2],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[3]) {
- if (!CompareArrays(orig->mTextureCoords[3],inst->mTextureCoords[3],orig->mNumVertices,uvEpsilon))
- continue;
- }
- }
- }
- }
-
- BOOST_STATIC_ASSERT(4 == AI_MAX_NUMBER_OF_COLOR_SETS);
-
- // and the same nasty stuff for vertex colors ...
- if (orig->mColors[0]) {
- if (!CompareArrays(orig->mColors[0],inst->mColors[0],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[1]) {
- if (!CompareArrays(orig->mColors[1],inst->mColors[1],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[2]) {
- if (!CompareArrays(orig->mColors[2],inst->mColors[2],orig->mNumVertices,uvEpsilon))
- continue;
- if (orig->mTextureCoords[3]) {
- if (!CompareArrays(orig->mColors[3],inst->mColors[3],orig->mNumVertices,uvEpsilon))
- continue;
- }
- }
- }
- }
-
- // These two checks are actually quite expensive and almost *never* required.
- // Almost. That's why they're still here. But there's no reason to do them
- // in speed-targeted imports.
- if (!configSpeedFlag) {
-
- // It seems to be strange, but we really need to check whether the
- // bones are identical too. Although it's extremely unprobable
- // that they're not if control reaches here, we need to deal
- // with unprobable cases, too. It could still be that there are
- // equal shapes which are deformed differently.
- if (!CompareBones(orig,inst))
- continue;
-
- // For completeness ... compare even the index buffers for equality
- // face order & winding order doesn't care. Input data is in verbose format.
- boost::scoped_array<unsigned int> ftbl_orig(new unsigned int[orig->mNumVertices]);
- boost::scoped_array<unsigned int> ftbl_inst(new unsigned int[orig->mNumVertices]);
-
- for (unsigned int tt = 0; tt < orig->mNumFaces;++tt) {
- aiFace& f = orig->mFaces[tt];
- for (unsigned int nn = 0; nn < f.mNumIndices;++nn)
- ftbl_orig[f.mIndices[nn]] = tt;
-
- aiFace& f2 = inst->mFaces[tt];
- for (unsigned int nn = 0; nn < f2.mNumIndices;++nn)
- ftbl_inst[f2.mIndices[nn]] = tt;
- }
- if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int)))
- continue;
- }
-
- // We're still here. Or in other words: 'inst' is an instance of 'orig'.
- // Place a marker in our list that we can easily update mesh indices.
- remapping[i] = remapping[a];
-
- // Delete the instanced mesh, we don't need it anymore
- delete inst;
- pScene->mMeshes[i] = NULL;
- break;
- }
- }
-
- // If we didn't find a match for the current mesh: keep it
- if (pScene->mMeshes[i]) {
- remapping[i] = numMeshesOut++;
- }
- }
- ai_assert(0 != numMeshesOut);
- if (numMeshesOut != pScene->mNumMeshes) {
-
- // Collapse the meshes array by removing all NULL entries
- for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) {
- if (pScene->mMeshes[i])
- pScene->mMeshes[real++] = pScene->mMeshes[i];
- }
-
- // And update the nodegraph with our nice lookup table
- UpdateMeshIndices(pScene->mRootNode,remapping.get());
-
- // write to log
- if (!DefaultLogger::isNullLogger()) {
-
- char buffer[512];
- ::sprintf(buffer,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
- DefaultLogger::get()->info(buffer);
- }
- pScene->mNumMeshes = numMeshesOut;
- }
- else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found");
- }
-}
diff --git a/3rdparty/assimp/code/FindInstancesProcess.h b/3rdparty/assimp/code/FindInstancesProcess.h
deleted file mode 100644
index bba2cada..00000000
--- a/3rdparty/assimp/code/FindInstancesProcess.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file FindInstancesProcess.h
- * @brief Declares the aiProcess_FindInstances post-process step
- */
-#ifndef AI_FINDINSTANCES_H_INC
-#define AI_FINDINSTANCES_H_INC
-
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
-
-class FindInstancesProcessTest;
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-/** @brief Get a pseudo(!)-hash representing a mesh.
- *
- * The hash is built from number of vertices, faces, primitive types,
- * .... but *not* from the real mesh data. It isn't absolutely unique.
- * @param in Input mesh
- * @return Hash.
- */
-inline uint64_t GetMeshHash(aiMesh* in)
-{
- ai_assert(NULL != in);
-
- // ... get an unique value representing the vertex format of the mesh
- const unsigned int fhash = GetMeshVFormatUnique(in);
-
- // and bake it with number of vertices/faces/bones/matidx/ptypes
- return ((uint64_t)fhash << 32u) | ((
- (in->mNumBones << 16u) ^ (in->mNumVertices) ^
- (in->mNumFaces<<4u) ^ (in->mMaterialIndex<<15) ^
- (in->mPrimitiveTypes<<28)) & 0xffffffff );
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Perform a component-wise comparison of two arrays
- *
- * @param first First array
- * @param second Second aray
- * @param size Size of both arrays
- * @param e Epsilon
- * @return true if the arrays are identical
- */
-inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
- unsigned int size, float e)
-{
- for (const aiVector3D* end = first+size; first != end; ++first,++second) {
- if ( (*first - *second).SquareLength() >= e)
- return false;
- }
- return true;
-}
-
-// and the same for colors ...
-inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
- unsigned int size, float e)
-{
- for (const aiColor4D* end = first+size; first != end; ++first,++second) {
- if ( GetColorDifference(*first,*second) >= e)
- return false;
- }
- return true;
-}
-
-// ---------------------------------------------------------------------------
-/** @brief A post-processing steps to search for instanced meshes
-*/
-class ASSIMP_API FindInstancesProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::FindInstancesProcessTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- FindInstancesProcess();
-
- /** Destructor, private as well */
- ~FindInstancesProcess();
-
-public:
- // -------------------------------------------------------------------
- // Check whether step is active in given flags combination
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup properties prior to executing the process
- void SetupProperties(const Importer* pImp);
-
-private:
-
- bool configSpeedFlag;
-
-}; // ! end class FindInstancesProcess
-} // ! end namespace Assimp
-
-#endif // !! AI_FINDINSTANCES_H_INC
diff --git a/3rdparty/assimp/code/FindInvalidDataProcess.cpp b/3rdparty/assimp/code/FindInvalidDataProcess.cpp
deleted file mode 100644
index 4e2d3cbd..00000000
--- a/3rdparty/assimp/code/FindInvalidDataProcess.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to search an importer's output
- for data that is obviously invalid */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-
-// internal headers
-#include "FindInvalidDataProcess.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindInvalidDataProcess::FindInvalidDataProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInvalidDataProcess::~FindInvalidDataProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FindInvalidData);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void FindInvalidDataProcess::SetupProperties(const Importer* pImp)
-{
- // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
- configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update mesh references in the node graph
-void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping)
-{
- if (node->mNumMeshes) {
- unsigned int out = 0;
- for (unsigned int a = 0; a < node->mNumMeshes;++a) {
-
- register unsigned int ref = node->mMeshes[a];
- if (0xffffffff != (ref = meshMapping[ref])) {
- node->mMeshes[out++] = ref;
- }
- }
- // just let the members that are unused, that's much cheaper
- // than a full array realloc'n'copy party ...
- if (!(node->mNumMeshes = out)) {
-
- delete[] node->mMeshes;
- node->mMeshes = NULL;
- }
- }
- // recursively update all children
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- UpdateMeshReferences(node->mChildren[i],meshMapping);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindInvalidDataProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FindInvalidDataProcess begin");
-
- bool out = false;
- std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
- unsigned int real = 0;
-
- // Process meshes
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
-
- int result;
- if ((result = ProcessMesh( pScene->mMeshes[a]))) {
- out = true;
-
- if (2 == result) {
- // remove this mesh
- delete pScene->mMeshes[a];
- AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
-
- meshMapping[a] = 0xffffffff;
- continue;
- }
- }
- pScene->mMeshes[real] = pScene->mMeshes[a];
- meshMapping[a] = real++;
- }
-
- // Process animations
- for (unsigned int a = 0; a < pScene->mNumAnimations;++a) {
- ProcessAnimation( pScene->mAnimations[a]);
- }
-
-
- if (out) {
- if ( real != pScene->mNumMeshes) {
- if (!real) {
- throw DeadlyImportError("No meshes remaining");
- }
-
- // we need to remove some meshes.
- // therefore we'll also need to remove all references
- // to them from the scenegraph
- UpdateMeshReferences(pScene->mRootNode,meshMapping);
- pScene->mNumMeshes = real;
- }
-
- DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ...");
- }
- else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK.");
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline const char* ValidateArrayContents(const T* arr, unsigned int size,
- const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
-{
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size,
- const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero )
-{
- bool b = false;
- unsigned int cnt = 0;
- for (unsigned int i = 0; i < size;++i) {
-
- if (dirtyMask.size() && dirtyMask[i]) {
- continue;
- }
- ++cnt;
-
- const aiVector3D& v = arr[i];
- if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) {
- return "INF/NAN was found in a vector component";
- }
- if (!mayBeZero && !v.x && !v.y && !v.z ) {
- return "Found zero-length vector";
- }
- if (i && v != arr[i-1])b = true;
- }
- if (cnt > 1 && !b && !mayBeIdentical) {
- return "All vectors are identical";
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline bool ProcessArray(T*& in, unsigned int num,const char* name,
- const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
-{
- const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero);
- if (err) {
- DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err);
-
- delete[] in;
- in = NULL;
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon);
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) {
- return fabs(n-s)>epsilon;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, float epsilon) {
- return
- EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
- EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
- EpsilonCompare(n.mValue.z,s.mValue.z,epsilon);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, float epsilon) {
- return
- EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
- EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
- EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) &&
- EpsilonCompare(n.mValue.w,s.mValue.w,epsilon);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline bool AllIdentical(T* in, unsigned int num, float epsilon)
-{
- if (num <= 1) {
- return true;
- }
-
- if (epsilon > 0.f) {
- for (unsigned int i = 0; i < num-1;++i) {
-
- if (!EpsilonCompare(in[i],in[i+1],epsilon)) {
- return false;
- }
- }
- }
- else {
- for (unsigned int i = 0; i < num-1;++i) {
-
- if (in[i] != in[i+1]) {
- return false;
- }
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search an animation for invalid content
-void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
-{
- // Process all animation channels
- for (unsigned int a = 0; a < anim->mNumChannels;++a) {
- ProcessAnimationChannel( anim->mChannels[a]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
-{
- int i = 0;
-
- // ScenePreprocessor's work ...
- ai_assert((0 != anim->mPositionKeys && 0 != anim->mRotationKeys && 0 != anim->mScalingKeys));
-
- // Check whether all values in a tracks are identical - in this case
- // we can remove al keys except one.
- // POSITIONS
- if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon))
- {
- aiVectorKey v = anim->mPositionKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mPositionKeys;
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1];
- anim->mPositionKeys[0] = v;
- i = 1;
- }
-
- // ROTATIONS
- if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon))
- {
- aiQuatKey v = anim->mRotationKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mRotationKeys;
- anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1];
- anim->mRotationKeys[0] = v;
- i = 1;
- }
-
- // SCALINGS
- if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon))
- {
- aiVectorKey v = anim->mScalingKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mScalingKeys;
- anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1];
- anim->mScalingKeys[0] = v;
- i = 1;
- }
- if (1 == i)
- DefaultLogger::get()->warn("Simplified dummy tracks with just one key");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search a mesh for invalid contents
-int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
-{
- bool ret = false;
- std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
-
- // Ignore elements that are not referenced by vertices.
- // (they are, for example, caused by the FindDegenerates step)
- for (unsigned int m = 0; m < pMesh->mNumFaces;++m) {
- const aiFace& f = pMesh->mFaces[m];
-
- for (unsigned int i = 0; i < f.mNumIndices;++i) {
- dirtyMask[f.mIndices[i]] = false;
- }
- }
-
- // Process vertex positions
- if (pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) {
- DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
- return 2;
- }
-
- // process texture coordinates
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) {
- if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) {
-
- // delete all subsequent texture coordinate sets.
- for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
- delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL;
- }
- ret = true;
- }
- }
-
- // -- we don't validate vertex colors, it's difficult to say whether
- // they are invalid or not.
-
- // Normals and tangents are undefined for point and line faces.
- if (pMesh->mNormals || pMesh->mTangents) {
-
- if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
- aiPrimitiveType_LINE & pMesh->mPrimitiveTypes)
- {
- if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
- aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes)
- {
- // We need to update the lookup-table
- for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
- {
- const aiFace& f = pMesh->mFaces[m];
-
- if (f.mNumIndices < 3) {
- dirtyMask[f.mIndices[0]] = true;
-
- if (f.mNumIndices == 2) {
- dirtyMask[f.mIndices[1]] = true;
- }
- }
- }
- }
- // Normals, tangents and bitangents are undefined for
- // the whole mesh (and should not even be there)
- else return ret;
- }
-
- // Process mesh normals
- if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices,
- "normals",dirtyMask,true,false))
- ret = true;
-
- // Process mesh tangents
- if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) {
- delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
- ret = true;
- }
-
- // Process mesh bitangents
- if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) {
- delete[] pMesh->mTangents; pMesh->mTangents = NULL;
- ret = true;
- }
- }
- return ret ? 1 : 0;
-}
-
-
-#endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
diff --git a/3rdparty/assimp/code/FindInvalidDataProcess.h b/3rdparty/assimp/code/FindInvalidDataProcess.h
deleted file mode 100644
index 304a0ff2..00000000
--- a/3rdparty/assimp/code/FindInvalidDataProcess.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to search an importer's output
- for data that is obviously invalid */
-#ifndef AI_FINDINVALIDDATA_H_INC
-#define AI_FINDINVALIDDATA_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiTypes.h"
-
-struct aiMesh;
-class FindInvalidDataProcessTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** The FindInvalidData postprocessing step. It searches the mesh data
- * for parts that are obviously invalid and removes them.
- *
- * Originally this was a workaround for some models written by Blender
- * which have zero normal vectors. */
-class ASSIMP_API FindInvalidDataProcess
- : public BaseProcess
-{
- friend class Importer;
- friend class ::FindInvalidDataProcessTest;
-
-protected:
-
- /** Constructor to be privately used by Importer */
- FindInvalidDataProcess();
-
- /** Destructor, private as well */
- ~FindInvalidDataProcess();
-
-public:
-
- // -------------------------------------------------------------------
- //
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- // Run the step
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given mesh
- * @param pMesh The mesh to process.
- * @return 0 - nothing, 1 - removed sth, 2 - please delete me */
- int ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given animation
- * @param anim The animation to process. */
- void ProcessAnimation (aiAnimation* anim);
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given anim channel
- * @param anim The animation channel to process.*/
- void ProcessAnimationChannel (aiNodeAnim* anim);
-
-private:
- float configEpsilon;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_AI_FINDINVALIDDATA_H_INC
diff --git a/3rdparty/assimp/code/FixNormalsStep.cpp b/3rdparty/assimp/code/FixNormalsStep.cpp
deleted file mode 100644
index fd10f4d1..00000000
--- a/3rdparty/assimp/code/FixNormalsStep.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to invert
- * all normals in meshes with infacing normals.
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "FixNormalsStep.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FixInfacingNormalsProcess::FixInfacingNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FixInfacingNormalsProcess::~FixInfacingNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_FixInfacingNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FixInfacingNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FixInfacingNormalsProcess begin");
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- if (ProcessMesh( pScene->mMeshes[a],a))bHas = true;
-
- if (bHas)
- DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues.");
- else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apply the step to the mesh
-bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
-{
- ai_assert(NULL != pcMesh);
-
- // Nothing to do if there are no model normals
- if (!pcMesh->HasNormals())return false;
-
- // Compute the bounding box of both the model vertices + normals and
- // the umodified model vertices. Then check whether the first BB
- // is smaller than the second. In this case we can assume that the
- // normals need to be flipped, although there are a few special cases ..
- // convex, concave, planar models ...
-
- aiVector3D vMin0 (1e10f,1e10f,1e10f);
- aiVector3D vMin1 (1e10f,1e10f,1e10f);
- aiVector3D vMax0 (-1e10f,-1e10f,-1e10f);
- aiVector3D vMax1 (-1e10f,-1e10f,-1e10f);
-
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- {
- vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x);
- vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y);
- vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z);
-
- vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x);
- vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
- vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
-
- const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
-
- vMin0.x = std::min(vMin0.x,vWithNormal.x);
- vMin0.y = std::min(vMin0.y,vWithNormal.y);
- vMin0.z = std::min(vMin0.z,vWithNormal.z);
-
- vMax0.x = std::max(vMax0.x,vWithNormal.x);
- vMax0.y = std::max(vMax0.y,vWithNormal.y);
- vMax0.z = std::max(vMax0.z,vWithNormal.z);
- }
-
- const float fDelta0_x = (vMax0.x - vMin0.x);
- const float fDelta0_y = (vMax0.y - vMin0.y);
- const float fDelta0_z = (vMax0.z - vMin0.z);
-
- const float fDelta1_x = (vMax1.x - vMin1.x);
- const float fDelta1_y = (vMax1.y - vMin1.y);
- const float fDelta1_z = (vMax1.z - vMin1.z);
-
- // Check whether the boxes are overlapping
- if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false;
- if ((fDelta0_y > 0.0f) != (fDelta1_y > 0.0f))return false;
- if ((fDelta0_z > 0.0f) != (fDelta1_z > 0.0f))return false;
-
- // Check whether this is a planar surface
- const float fDelta1_yz = fDelta1_y * fDelta1_z;
-
- if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
- if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false;
- if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
-
- // now compare the volumes of the bounding boxes
- if (::fabsf(fDelta0_x * fDelta1_yz) <
- ::fabsf(fDelta1_x * fDelta1_y * fDelta1_z))
- {
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[128]; // should be sufficiently large
- ::sprintf(buffer,"Mesh %i: Normals are facing inwards (or the mesh is planar)",index);
- DefaultLogger::get()->info(buffer);
- }
-
- // Invert normals
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- pcMesh->mNormals[i] *= -1.0f;
-
- // ... and flip faces
- for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
- {
- aiFace& face = pcMesh->mFaces[i];
- for ( unsigned int b = 0; b < face.mNumIndices / 2; b++)
- std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
- }
- return true;
- }
- return false;
-}
diff --git a/3rdparty/assimp/code/FixNormalsStep.h b/3rdparty/assimp/code/FixNormalsStep.h
deleted file mode 100644
index 972001e8..00000000
--- a/3rdparty/assimp/code/FixNormalsStep.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines a post processing step to fix infacing normals */
-#ifndef AI_FIXNORMALSPROCESS_H_INC
-#define AI_FIXNORMALSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The FixInfacingNormalsProcess tries to deteermine whether the normal
- * vectors of an object are facing inwards. In this case they will be
- * flipped.
- */
- class ASSIMP_API FixInfacingNormalsProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- FixInfacingNormalsProcess();
-
- /** Destructor, private as well */
- ~FixInfacingNormalsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the step on the given mesh
- * @param pMesh The mesh to process.
- */
- bool ProcessMesh( aiMesh* pMesh, unsigned int index);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_FIXNORMALSPROCESS_H_INC
diff --git a/3rdparty/assimp/code/GenFaceNormalsProcess.cpp b/3rdparty/assimp/code/GenFaceNormalsProcess.cpp
deleted file mode 100644
index f0987c85..00000000
--- a/3rdparty/assimp/code/GenFaceNormalsProcess.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to generate face
-* normals for all imported faces.
-*/
-
-#include "AssimpPCH.h"
-#include "GenFaceNormalsProcess.h"
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-GenFaceNormalsProcess::GenFaceNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenFaceNormalsProcess::~GenFaceNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenFaceNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
- }
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- if (this->GenMeshFaceNormals( pScene->mMeshes[a])) {
- bHas = true;
- }
- }
- if (bHas) {
- DefaultLogger::get()->info("GenFaceNormalsProcess finished. "
- "Face normals have been calculated");
- }
- else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. "
- "Normals are already there");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
-{
- if (NULL != pMesh->mNormals) {
- return false;
- }
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
- DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
- return false;
- }
-
- // allocate an array to hold the output normals
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- const float qnan = get_qnan();
-
- // iterate through all faces and compute per-face normals but store them per-vertex.
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3) {
- // either a point or a line -> no well-defined normal vector
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = qnan;
- }
- continue;
- }
-
- const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
- const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
- const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
- aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
-
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = vNor;
- }
- }
- return true;
-}
diff --git a/3rdparty/assimp/code/GenFaceNormalsProcess.h b/3rdparty/assimp/code/GenFaceNormalsProcess.h
deleted file mode 100644
index 87ca6f22..00000000
--- a/3rdparty/assimp/code/GenFaceNormalsProcess.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to compute face normals for all loaded faces*/
-#ifndef AI_GENFACENORMALPROCESS_H_INC
-#define AI_GENFACENORMALPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
-*/
-class ASSIMP_API GenFaceNormalsProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- GenFaceNormalsProcess();
-
- /** Destructor, private as well */
- ~GenFaceNormalsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
-private:
- bool GenMeshFaceNormals (aiMesh* pcMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENFACENORMALPROCESS_H_INC
diff --git a/3rdparty/assimp/code/GenVertexNormalsProcess.cpp b/3rdparty/assimp/code/GenVertexNormalsProcess.cpp
deleted file mode 100644
index 260ad68f..00000000
--- a/3rdparty/assimp/code/GenVertexNormalsProcess.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to generate face
-* normals for all imported faces.
-*/
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "GenVertexNormalsProcess.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-GenVertexNormalsProcess::GenVertexNormalsProcess()
-{
- this->configMaxAngle = AI_DEG_TO_RAD(175.f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenVertexNormalsProcess::~GenVertexNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenSmoothNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
-{
- // Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property
- configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,175.f);
- configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle,175.0f),0.0f));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenVertexNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenVertexNormalsProcess begin");
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if (GenMeshVertexNormals( pScene->mMeshes[a],a))
- bHas = true;
- }
-
- if (bHas) {
- DefaultLogger::get()->info("GenVertexNormalsProcess finished. "
- "Vertex normals have been calculated");
- }
- else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. "
- "Normals are already there");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
-{
- if (NULL != pMesh->mNormals)
- return false;
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
- {
- DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
- return false;
- }
-
- // Allocate the array to hold the output normals
- const float qnan = std::numeric_limits<float>::quiet_NaN();
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-
- // Compute per-face normals but store them per-vertex
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3)
- {
- // either a point or a line -> no normal vector
- for (unsigned int i = 0;i < face.mNumIndices;++i)
- pMesh->mNormals[face.mIndices[i]] = qnan;
- continue;
- }
-
- aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
- aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
- aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
- aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
-
- for (unsigned int i = 0;i < face.mNumIndices;++i)
- pMesh->mNormals[face.mIndices[i]] = vNor;
- }
-
- // Set up a SpatialSort to quickly find all vertices close to a given position
- // check whether we can reuse the SpatialSort of a previous step.
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
- float posEpsilon = 1e-5f;
- if (shared) {
- std::vector<std::pair<SpatialSort,float> >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf)
- {
- std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
- vertexFinder = &blubb.first;
- posEpsilon = blubb.second;
- }
- }
- if (!vertexFinder) {
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- posEpsilon = ComputePositionEpsilon(pMesh);
- }
- std::vector<unsigned int> verticesFound;
- aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
-
- if (configMaxAngle >= AI_DEG_TO_RAD( 175.f )) {
- // There is no angle limit. Thus all vertices with positions close
- // to each other will receive the same vertex normal. This allows us
- // to optimize the whole algorithm a little bit ...
- std::vector<bool> abHad(pMesh->mNumVertices,false);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- if (abHad[i])continue;
-
- // Get all vertices that share this one ...
- vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
-
- aiVector3D pcNor;
- for (unsigned int a = 0; a < verticesFound.size(); ++a) {
- const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
- if (is_not_qnan(v.x))pcNor += v;
- }
- pcNor.Normalize();
-
- // Write the smoothed normal back to all affected normals
- for (unsigned int a = 0; a < verticesFound.size(); ++a)
- {
- register unsigned int vidx = verticesFound[a];
- pcNew[vidx] = pcNor;
- abHad[vidx] = true;
- }
- }
- }
- // Slower code path if a smooth angle is set. There are many ways to achieve
- // the effect, this one is the most straightforward one.
- else {
- const float fLimit = ::cos(configMaxAngle);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- // Get all vertices that share this one ...
- vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
-
- aiVector3D pcNor;
- for (unsigned int a = 0; a < verticesFound.size(); ++a) {
- const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
-
- // check whether the angle between the two normals is not too large
- // HACK: if v.x is qnan the dot product will become qnan, too
- // therefore the comparison against fLimit should be false
- // in every case.
- if (v * pMesh->mNormals[i] < fLimit)
- continue;
-
- pcNor += v;
- }
- pcNew[i] = pcNor.Normalize();
- }
- }
-
- delete[] pMesh->mNormals;
- pMesh->mNormals = pcNew;
-
- return true;
-}
diff --git a/3rdparty/assimp/code/GenVertexNormalsProcess.h b/3rdparty/assimp/code/GenVertexNormalsProcess.h
deleted file mode 100644
index 294cb7ef..00000000
--- a/3rdparty/assimp/code/GenVertexNormalsProcess.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to compute vertex normals
- for all loaded vertizes */
-#ifndef AI_GENVERTEXNORMALPROCESS_H_INC
-#define AI_GENVERTEXNORMALPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class GenNormalsTest;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes vertex normals for all vertizes
-*/
-class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::GenNormalsTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- GenVertexNormalsProcess();
-
- /** Destructor, private as well */
- ~GenVertexNormalsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
- // setter for configMaxAngle
- inline void SetMaxSmoothAngle(float f)
- {
- configMaxAngle =f;
- }
-
-protected:
-
- // -------------------------------------------------------------------
- /** Computes normals for a specific mesh
- * @param pcMesh Mesh
- * @param meshIndex Index of the mesh
- * @return true if vertex normals have been computed
- */
- bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
-
-private:
-
- /** Configuration option: maximum smoothing angle, in radians*/
- float configMaxAngle;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC
-
diff --git a/3rdparty/assimp/code/GenericProperty.h b/3rdparty/assimp/code/GenericProperty.h
deleted file mode 100644
index c64d392f..00000000
--- a/3rdparty/assimp/code/GenericProperty.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
-#define AI_GENERIC_PROPERTY_H_INCLUDED
-
-#include "./../include/assimp.hpp"
-#include "Hash.h"
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void SetGenericProperty(std::map< unsigned int, T >& list,
- const char* szName, const T& value, bool* bWasExisting = NULL)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T>::iterator it = list.find(hash);
- if (it == list.end()) {
- if (bWasExisting)
- *bWasExisting = false;
- list.insert(std::pair<unsigned int, T>( hash, value ));
- return;
- }
- (*it).second = value;
- if (bWasExisting)
- *bWasExisting = true;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
- const char* szName, const T& errorReturn)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
- if (it == list.end())
- return errorReturn;
-
- return (*it).second;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Special version for pointer types - they will be deleted when replaced with another value
-// passing NULL removes the whole property
-template <class T>
-inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
- const char* szName, T* value, bool* bWasExisting = NULL)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T*>::iterator it = list.find(hash);
- if (it == list.end()) {
- if (bWasExisting)
- *bWasExisting = false;
-
- list.insert(std::pair<unsigned int,T*>( hash, value ));
- return;
- }
- if ((*it).second != value) {
- delete (*it).second;
- (*it).second = value;
- }
- if (!value) {
- list.erase(it);
- }
- if (bWasExisting)
- *bWasExisting = true;
-}
-
-
-#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
diff --git a/3rdparty/assimp/code/HMPFileData.h b/3rdparty/assimp/code/HMPFileData.h
deleted file mode 100644
index 5ac01bd9..00000000
--- a/3rdparty/assimp/code/HMPFileData.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-//!
-//! @file Data structures for the 3D Game Studio Heightmap format (HMP)
-//!
-
-namespace Assimp {
-namespace HMP {
-
-#include "./../include/Compiler/pushpack1.h"
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_HMP_MAGIC_NUMBER_BE_4 AI_MAKE_MAGIC("HMP4")
-#define AI_HMP_MAGIC_NUMBER_LE_4 AI_MAKE_MAGIC("4PMH")
-
-#define AI_HMP_MAGIC_NUMBER_BE_5 AI_MAKE_MAGIC("HMP5")
-#define AI_HMP_MAGIC_NUMBER_LE_5 AI_MAKE_MAGIC("5PMH")
-
-#define AI_HMP_MAGIC_NUMBER_BE_7 AI_MAKE_MAGIC("HMP7")
-#define AI_HMP_MAGIC_NUMBER_LE_7 AI_MAKE_MAGIC("7PMH")
-
-// ---------------------------------------------------------------------------
-/** Data structure for the header of a HMP5 file.
- * This is also used by HMP4 and HMP7, but with modifications
-*/
-struct Header_HMP5
-{
- int8_t ident[4]; // "HMP5"
- int32_t version;
-
- // ignored
- float scale[3];
- float scale_origin[3];
- float boundingradius;
-
- //! Size of one triangle in x direction
- float ftrisize_x;
- //! Size of one triangle in y direction
- float ftrisize_y;
- //! Number of vertices in x direction
- float fnumverts_x;
-
- //! Number of skins in the file
- int32_t numskins;
-
- // can ignore this?
- int32_t skinwidth;
- int32_t skinheight;
-
- //!Number of vertices in the file
- int32_t numverts;
-
- // ignored and zero
- int32_t numtris;
-
- //! only one supported ...
- int32_t numframes;
-
- //! Always 0 ...
- int32_t num_stverts;
- int32_t flags;
- float size;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP4 file
-*/
-struct Vertex_HMP4
-{
- uint16_t p_pos[3];
- uint8_t normals162index;
- uint8_t pad;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP5 file
-*/
-struct Vertex_HMP5
-{
- uint16_t z;
- uint8_t normals162index;
- uint8_t pad;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP7 file
-*/
-struct Vertex_HMP7
-{
- uint16_t z;
- int8_t normal_x,normal_y;
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-} //! namespace HMP
-} //! namespace Assimp
diff --git a/3rdparty/assimp/code/HMPLoader.cpp b/3rdparty/assimp/code/HMPLoader.cpp
deleted file mode 100644
index f9323687..00000000
--- a/3rdparty/assimp/code/HMPLoader.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the MDL importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-
-// internal headers
-#include "MaterialSystem.h"
-#include "HMPLoader.h"
-#include "MD2FileData.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-HMPImporter::HMPImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-HMPImporter::~HMPImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "hmp" )
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || cs) {
- uint32_t tokens[3];
- tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
- tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
- tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
- return CheckMagicToken(pIOHandler,pFile,tokens,3,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of all file extensions that are handled by this loader
-void HMPImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("hmp");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void HMPImporter::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pScene = _pScene;
- pIOHandler = _pIOHandler;
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
-
- // Check whether the HMP file is large enough to contain
- // at least the file header
- const size_t fileSize = file->FileSize();
- if ( fileSize < 50)
- throw DeadlyImportError( "HMP File is too small.");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<uint8_t> buffer(fileSize);
- mBuffer = &buffer[0];
- file->Read( (void*)mBuffer, 1, fileSize);
- iFileSize = (unsigned int)fileSize;
-
- // Determine the file subtype and call the appropriate member function
- const uint32_t iMagic = *((uint32_t*)this->mBuffer);
-
- // HMP4 format
- if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A4, magic word is HMP4");
- InternReadFile_HMP4();
- }
- // HMP5 format
- else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A5, magic word is HMP5");
- InternReadFile_HMP5();
- }
- // HMP7 format
- else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A7, magic word is HMP7");
- InternReadFile_HMP7();
- }
- else
- {
- // Print the magic word to the logger
- char szBuffer[5];
- szBuffer[0] = ((char*)&iMagic)[0];
- szBuffer[1] = ((char*)&iMagic)[1];
- szBuffer[2] = ((char*)&iMagic)[2];
- szBuffer[3] = ((char*)&iMagic)[3];
- szBuffer[4] = '\0';
-
- // We're definitely unable to load this file
- throw DeadlyImportError( "Unknown HMP subformat " + pFile +
- ". Magic word (" + szBuffer + ") is not known");
- }
-
- // Set the AI_SCENE_FLAGS_TERRAIN bit
- pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
-
- // File buffer destructs automatically now
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::ValidateHeader_HMP457( )
-{
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
-
- if (120 > iFileSize)
- {
- throw DeadlyImportError("HMP file is too small (header size is "
- "120 bytes, this file is smaller)");
- }
-
- if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y)
- throw DeadlyImportError("Size of triangles in either x or y direction is zero");
-
- if (pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f)
- throw DeadlyImportError("Number of triangles in either x or y direction is zero");
-
- if (!pcHeader->numframes)
- throw DeadlyImportError("There are no frames. At least one should be there");
-
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP4( )
-{
- throw DeadlyImportError("HMP4 is currently not supported");
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP5( )
-{
- // read the file header and skip everything to byte 84
- const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
- ValidateHeader_HMP457();
-
- // generate an output mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
-
- pcMesh->mMaterialIndex = 0;
- pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
- pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
-
- const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
- const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
-
- // generate/load a material for the terrain
- CreateMaterial(szCurrent,&szCurrent);
-
- // goto offset 120, I don't know why ...
- // (fixme) is this the frame header? I assume yes since it starts with 2.
- szCurrent += 36;
- SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
-
- // now load all vertices from the file
- aiVector3D* pcVertOut = pcMesh->mVertices;
- aiVector3D* pcNorOut = pcMesh->mNormals;
- const HMP::Vertex_HMP5* src = (const HMP::Vertex_HMP5*) szCurrent;
- for (unsigned int y = 0; y < height;++y)
- {
- for (unsigned int x = 0; x < width;++x)
- {
- pcVertOut->x = x * pcHeader->ftrisize_x;
- pcVertOut->y = y * pcHeader->ftrisize_y;
- pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
- MD2::LookupNormalIndex(src->normals162index, *pcNorOut );
- ++pcVertOut;++pcNorOut;++src;
- }
- }
-
- // generate texture coordinates if necessary
- if (pcHeader->numskins)
- GenerateTextureCoords(width,height);
-
- // now build a list of faces
- CreateOutputFaceList(width,height);
-
- // there is no nodegraph in HMP files. Simply assign the one mesh
- // (no, not the one ring) to the root node
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("terrain_root");
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP7( )
-{
- // read the file header and skip everything to byte 84
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
- ValidateHeader_HMP457();
-
- // generate an output mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
-
- pcMesh->mMaterialIndex = 0;
- pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
- pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
-
- const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
- const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
-
- // generate/load a material for the terrain
- CreateMaterial(szCurrent,&szCurrent);
-
- // goto offset 120, I don't know why ...
- // (fixme) is this the frame header? I assume yes since it starts with 2.
- szCurrent += 36;
-
- SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
-
- // now load all vertices from the file
- aiVector3D* pcVertOut = pcMesh->mVertices;
- aiVector3D* pcNorOut = pcMesh->mNormals;
- const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent;
- for (unsigned int y = 0; y < height;++y)
- {
- for (unsigned int x = 0; x < width;++x)
- {
- pcVertOut->x = x * pcHeader->ftrisize_x;
- pcVertOut->y = y * pcHeader->ftrisize_y;
-
- // FIXME: What exctly is the correct scaling factor to use?
- // possibly pcHeader->scale_origin[2] in combination with a
- // signed interpretation of src->z?
- pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
-
- pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0];
- pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1];
- pcNorOut->z = 1.0f;
- pcNorOut->Normalize();
-
- ++pcVertOut;++pcNorOut;++src;
- }
- }
-
- // generate texture coordinates if necessary
- if (pcHeader->numskins)GenerateTextureCoords(width,height);
-
- // now build a list of faces
- CreateOutputFaceList(width,height);
-
- // there is no nodegraph in HMP files. Simply assign the one mesh
- // (no, not the One Ring) to the root node
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("terrain_root");
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::CreateMaterial(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut)
-{
- aiMesh* const pcMesh = pScene->mMeshes[0];
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
-
- // we don't need to generate texture coordinates if
- // we have no textures in the file ...
- if (pcHeader->numskins)
- {
- pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
- pcMesh->mNumUVComponents[0] = 2;
-
- // now read the first skin and skip all others
- ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent);
- }
- else
- {
- // generate a default material
- const int iMode = (int)aiShadingMode_Gouraud;
- MaterialHelper* pcHelper = new MaterialHelper();
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- // add the material to the scene
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcHelper;
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
-{
- aiMesh* const pcMesh = this->pScene->mMeshes[0];
-
- // Allocate enough storage
- pcMesh->mNumFaces = (width-1) * (height-1);
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- pcMesh->mNumVertices = pcMesh->mNumFaces*4;
- aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcNormals = new aiVector3D[pcMesh->mNumVertices];
-
- aiFace* pcFaceOut(pcMesh->mFaces);
- aiVector3D* pcVertOut = pcVertices;
- aiVector3D* pcNorOut = pcNormals;
-
- aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
- aiVector3D* pcUVOut(pcUVs);
-
- // Build the terrain square
- unsigned int iCurrent = 0;
- for (unsigned int y = 0; y < height-1;++y) {
- for (unsigned int x = 0; x < width-1;++x,++pcFaceOut) {
- pcFaceOut->mNumIndices = 4;
- pcFaceOut->mIndices = new unsigned int[4];
-
- *pcVertOut++ = pcMesh->mVertices[y*width+x];
- *pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
- *pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1];
- *pcVertOut++ = pcMesh->mVertices[y*width+x+1];
-
-
- *pcNorOut++ = pcMesh->mNormals[y*width+x];
- *pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
- *pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1];
- *pcNorOut++ = pcMesh->mNormals[y*width+x+1];
-
- if (pcMesh->mTextureCoords[0])
- {
- *pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
- *pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
- *pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
- *pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
- }
-
- for (unsigned int i = 0; i < 4;++i)
- pcFaceOut->mIndices[i] = iCurrent++;
- }
- }
- delete[] pcMesh->mVertices;
- pcMesh->mVertices = pcVertices;
-
- delete[] pcMesh->mNormals;
- pcMesh->mNormals = pcNormals;
-
- if (pcMesh->mTextureCoords[0])
- {
- delete[] pcMesh->mTextureCoords[0];
- pcMesh->mTextureCoords[0] = pcUVs;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
- const unsigned char** szCursorOut)
-{
- ai_assert(0 != iNumSkins && NULL != szCursor);
-
- // read the type of the skin ...
- // sometimes we need to skip 12 bytes here, I don't know why ...
- uint32_t iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
- if (0 == iType)
- {
- szCursor += sizeof(uint32_t) * 2;
- iType = *((uint32_t*)szCursor);szCursor += sizeof(uint32_t);
- if (!iType)
- throw DeadlyImportError("Unable to read HMP7 skin chunk");
-
- }
- // read width and height
- uint32_t iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
-
- // allocate an output material
- MaterialHelper* pcMat = new MaterialHelper();
-
- // read the skin, this works exactly as for MDL7
- ParseSkinLump_3DGS_MDL7(szCursor,&szCursor,
- pcMat,iType,iWidth,iHeight);
-
- // now we need to skip any other skins ...
- for (unsigned int i = 1; i< iNumSkins;++i)
- {
- iType = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
-
- SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,iType,iWidth,iHeight);
- SizeCheck(szCursor);
- }
-
- // setup the material ...
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-
- *szCursorOut = szCursor;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate proepr texture coords
-void HMPImporter::GenerateTextureCoords(
- const unsigned int width, const unsigned int height)
-{
- ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] &&
- NULL != pScene->mMeshes[0]->mTextureCoords[0]);
-
- aiVector3D* uv = pScene->mMeshes[0]->mTextureCoords[0];
-
- const float fY = (1.0f / height) + (1.0f / height) / (height-1);
- const float fX = (1.0f / width) + (1.0f / width) / (width-1);
-
- for (unsigned int y = 0; y < height;++y) {
- for (unsigned int x = 0; x < width;++x,++uv) {
- uv->y = fY*y;
- uv->x = fX*x;
- uv->z = 0.0f;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_HMP_IMPORTER
diff --git a/3rdparty/assimp/code/HMPLoader.h b/3rdparty/assimp/code/HMPLoader.h
deleted file mode 100644
index fdf84baa..00000000
--- a/3rdparty/assimp/code/HMPLoader.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-/** @file HMPLoader.h
- * @brief Declaration of the HMP importer class
- */
-
-#ifndef AI_HMPLOADER_H_INCLUDED
-#define AI_HMPLOADER_H_INCLUDED
-
-// public ASSIMP headers
-#include "../include/aiTypes.h"
-#include "../include/aiTexture.h"
-#include "../include/aiMaterial.h"
-
-// internal headers
-#include "BaseImporter.h"
-#include "MDLLoader.h"
-#include "HMPFileData.h"
-
-namespace Assimp {
-using namespace HMP;
-
-// ---------------------------------------------------------------------------
-/** Used to load 3D GameStudio HMP files (terrains)
-*/
-class HMPImporter : public MDLImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- HMPImporter();
-
- /** Destructor, private as well */
- ~HMPImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Import a HMP4 file
- */
- void InternReadFile_HMP4( );
-
- // -------------------------------------------------------------------
- /** Import a HMP5 file
- */
- void InternReadFile_HMP5( );
-
- // -------------------------------------------------------------------
- /** Import a HMP7 file
- */
- void InternReadFile_HMP7( );
-
- // -------------------------------------------------------------------
- /** Validate a HMP 5,4,7 file header
- */
- void ValidateHeader_HMP457( );
-
- // -------------------------------------------------------------------
- /** Try to load one material from the file, if this fails create
- * a default material
- */
- void CreateMaterial(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Build a list of output faces and vertices. The function
- * triangulates the height map read from the file
- * \param width Width of the height field
- * \param width Height of the height field
- */
- void CreateOutputFaceList(unsigned int width,unsigned int height);
-
- // -------------------------------------------------------------------
- /** Generate planar texture coordinates for a terrain
- * \param width Width of the terrain, in vertices
- * \param height Height of the terrain, in vertices
- */
- void GenerateTextureCoords(const unsigned int width,
- const unsigned int height);
-
- // -------------------------------------------------------------------
- /** Read the first skin from the file and skip all others ...
- * \param iNumSkins Number of skins in the file
- * \param szCursor Position of the first skin (offset 84)
- */
- void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
- const unsigned char** szCursorOut);
-
-private:
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_HMPIMPORTER_H_INC
-
diff --git a/3rdparty/assimp/code/HalfLifeFileData.h b/3rdparty/assimp/code/HalfLifeFileData.h
deleted file mode 100644
index ab2cbbd5..00000000
--- a/3rdparty/assimp/code/HalfLifeFileData.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-//
-//! @file Definition of in-memory structures for the HL2 MDL file format
-// and for the HalfLife text format (SMD)
-//
-// The specification has been taken from various sources on the internet.
-
-
-#ifndef AI_MDLFILEHELPER2_H_INC
-#define AI_MDLFILEHELPER2_H_INC
-
-#include "./../include/Compiler/pushpack1.h"
-
-#include "MDLFileData.h"
-
-namespace Assimp {
-namespace MDL {
-
-// magic bytes used in Half Life 2 MDL models
-#define AI_MDL_MAGIC_NUMBER_BE_HL2a AI_MAKE_MAGIC("IDST")
-#define AI_MDL_MAGIC_NUMBER_LE_HL2a AI_MAKE_MAGIC("TSDI")
-#define AI_MDL_MAGIC_NUMBER_BE_HL2b AI_MAKE_MAGIC("IDSQ")
-#define AI_MDL_MAGIC_NUMBER_LE_HL2b AI_MAKE_MAGIC("QSDI")
-
-// ---------------------------------------------------------------------------
-/** \struct Header_HL2
- * \brief Data structure for the HL2 main header
- */
-// ---------------------------------------------------------------------------
-struct Header_HL2
-{
- //! magic number: "IDST"/"IDSQ"
- char ident[4];
-
- //! Version number
- int32_t version;
-
- //! Original file name in pak ?
- char name[64];
-
- //! Length of file name/length of file?
- int32_t length;
-
- //! For viewer, ignored
- aiVector3D eyeposition;
- aiVector3D min;
- aiVector3D max;
-
- //! AABB of the model
- aiVector3D bbmin;
- aiVector3D bbmax;
-
- // File flags
- int32_t flags;
-
- //! NUmber of bones contained in the file
- int32_t numbones;
- int32_t boneindex;
-
- //! Number of bone controllers for bone animation
- int32_t numbonecontrollers;
- int32_t bonecontrollerindex;
-
- //! More bounding boxes ...
- int32_t numhitboxes;
- int32_t hitboxindex;
-
- //! Animation sequences in the file
- int32_t numseq;
- int32_t seqindex;
-
- //! Loaded sequences. Ignored
- int32_t numseqgroups;
- int32_t seqgroupindex;
-
- //! Raw texture data
- int32_t numtextures;
- int32_t textureindex;
- int32_t texturedataindex;
-
- //! Number of skins (=textures?)
- int32_t numskinref;
- int32_t numskinfamilies;
- int32_t skinindex;
-
- //! Number of parts
- int32_t numbodyparts;
- int32_t bodypartindex;
-
- //! attachable points for gameplay and physics
- int32_t numattachments;
- int32_t attachmentindex;
-
- //! Table of sound effects associated with the model
- int32_t soundtable;
- int32_t soundindex;
- int32_t soundgroups;
- int32_t soundgroupindex;
-
- //! Number of animation transitions
- int32_t numtransitions;
- int32_t transitionindex;
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-}
-} // end namespaces
-
-#endif // ! AI_MDLFILEHELPER2_H_INC
diff --git a/3rdparty/assimp/code/Hash.h b/3rdparty/assimp/code/Hash.h
deleted file mode 100644
index 9ba79c51..00000000
--- a/3rdparty/assimp/code/Hash.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef AI_HASH_H_INCLUDED
-#define AI_HASH_H_INCLUDED
-
-// ------------------------------------------------------------------------------------------------
-// hashing function taken from
-// http://www.azillionmonkeys.com/qed/hash.html
-// (incremental version of the hashing function)
-// (stdint.h should have been been included here)
-// ------------------------------------------------------------------------------------------------
-#undef get16bits
-#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
- || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
-#define get16bits(d) (*((const uint16_t *) (d)))
-#endif
-
-#if !defined (get16bits)
-#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
- +(uint32_t)(((const uint8_t *)(d))[0]) )
-#endif
-
-// ------------------------------------------------------------------------------------------------
-inline unsigned int SuperFastHash (const char * data, unsigned int len = 0, unsigned int hash = 0) {
-unsigned int tmp;
-int rem;
-
- if (!data) return 0;
- if (!len)len = (unsigned int)::strlen(data);
-
- rem = len & 3;
- len >>= 2;
-
- /* Main loop */
- for (;len > 0; len--) {
- hash += get16bits (data);
- tmp = (get16bits (data+2) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2*sizeof (uint16_t);
- hash += hash >> 11;
- }
-
- /* Handle end cases */
- switch (rem) {
- case 3: hash += get16bits (data);
- hash ^= hash << 16;
- hash ^= data[sizeof (uint16_t)] << 18;
- hash += hash >> 11;
- break;
- case 2: hash += get16bits (data);
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- case 1: hash += *data;
- hash ^= hash << 10;
- hash += hash >> 1;
- }
-
- /* Force "avalanching" of final 127 bits */
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 4;
- hash += hash >> 17;
- hash ^= hash << 25;
- hash += hash >> 6;
-
- return hash;
-}
-
-#endif // !! AI_HASH_H_INCLUDED
diff --git a/3rdparty/assimp/code/IFF.h b/3rdparty/assimp/code/IFF.h
deleted file mode 100644
index e1bfa210..00000000
--- a/3rdparty/assimp/code/IFF.h
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-// Definitions for the Interchange File Format (IFF)
-// Alexander Gessler, 2006
-// Adapted to Assimp August 2008
-
-#ifndef AI_IFF_H_INCLUDED
-#define AI_IFF_H_INCLUDED
-
-#include "ByteSwap.h"
-
-namespace Assimp {
-namespace IFF {
-
-#include "./../include/Compiler/pushpack1.h"
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Describes an IFF chunk header
-/////////////////////////////////////////////////////////////////////////////////
-struct ChunkHeader
-{
- //! Type of the chunk header - FourCC
- uint32_t type;
-
- //! Length of the chunk data, in bytes
- uint32_t length;
-} PACK_STRUCT;
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Describes an IFF sub chunk header
-/////////////////////////////////////////////////////////////////////////////////
-struct SubChunkHeader
-{
- //! Type of the chunk header - FourCC
- uint32_t type;
-
- //! Length of the chunk data, in bytes
- uint16_t length;
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-
-#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
- ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
-
-
-#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Load a chunk header
-//! @param outFile Pointer to the file data - points to the chunk data afterwards
-//! @return Pointer to the chunk header
-/////////////////////////////////////////////////////////////////////////////////
-inline ChunkHeader* LoadChunk(uint8_t*& outFile)
-{
- ChunkHeader* head = (ChunkHeader*) outFile;
- AI_LSWAP4(head->length);
- AI_LSWAP4(head->type);
- outFile += sizeof(ChunkHeader);
- return head;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Load a sub chunk header
-//! @param outFile Pointer to the file data - points to the chunk data afterwards
-//! @return Pointer to the sub chunk header
-/////////////////////////////////////////////////////////////////////////////////
-inline SubChunkHeader* LoadSubChunk(uint8_t*& outFile)
-{
- SubChunkHeader* head = (SubChunkHeader*) outFile;
- AI_LSWAP2(head->length);
- AI_LSWAP4(head->type);
- outFile += sizeof(SubChunkHeader);
- return head;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Read the file header and return the type of the file and its size
-//! @param outFile Pointer to the file data. The buffer must at
-//! least be 12 bytes large.
-//! @param fileType Receives the type of the file
-//! @return 0 if everything was OK, otherwise an error message
-/////////////////////////////////////////////////////////////////////////////////
-inline const char* ReadHeader(uint8_t* outFile,uint32_t& fileType)
-{
- ChunkHeader* head = LoadChunk(outFile);
- if (AI_IFF_FOURCC_FORM != head->type)
- {
- return "The file is not an IFF file: FORM chunk is missing";
- }
- fileType = *((uint32_t*)(head+1));
- AI_LSWAP4(fileType);
- return 0;
-}
-
-
-}}
-
-#endif // !! AI_IFF_H_INCLUDED
diff --git a/3rdparty/assimp/code/IRRLoader.cpp b/3rdparty/assimp/code/IRRLoader.cpp
deleted file mode 100644
index 20a94c09..00000000
--- a/3rdparty/assimp/code/IRRLoader.cpp
+++ /dev/null
@@ -1,1462 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file IRRLoader.cpp
- * @brief Implementation of the Irr importer class
- */
-
-#include "AssimpPCH.h"
-
-#include "IRRLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "GenericProperty.h"
-
-#include "SceneCombiner.h"
-#include "StandardShapes.h"
-
-
-// We need boost::common_factor to compute the lcm/gcd of a number
-#include <boost/math/common_factor_rt.hpp>
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IRRImporter::IRRImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IRRImporter::~IRRImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- /* NOTE: A simple check for the file extension is not enough
- * here. Irrmesh and irr are easy, but xml is too generic
- * and could be collada, too. So we need to open the file and
- * search for typical tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "irr")return true;
- else if (extension == "xml" || checkSig)
- {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"irr_scene"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("irr");
- extensions.insert("xml");
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::SetupProperties(const Importer* pImp)
-{
- // read the output frame rate of all node animation channels
- fps = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IRR_ANIM_FPS,100);
- if (fps < 10.) {
- DefaultLogger::get()->error("IRR: Invalid FPS configuration");
- fps = 100;
- }
-
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a mesh tha consists of a single squad (a side of a skybox)
-aiMesh* IRRImporter::BuildSingleQuadMesh(const SkyboxVertex& v1,
- const SkyboxVertex& v2,
- const SkyboxVertex& v3,
- const SkyboxVertex& v4)
-{
- // allocate and prepare the mesh
- aiMesh* out = new aiMesh();
-
- out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- out->mNumFaces = 1;
-
- // build the face
- out->mFaces = new aiFace[1];
- aiFace& face = out->mFaces[0];
-
- face.mNumIndices = 4;
- face.mIndices = new unsigned int[4];
- for (unsigned int i = 0; i < 4;++i)
- face.mIndices[i] = i;
-
- out->mNumVertices = 4;
-
- // copy vertex positions
- aiVector3D* vec = out->mVertices = new aiVector3D[4];
- *vec++ = v1.position;
- *vec++ = v2.position;
- *vec++ = v3.position;
- *vec = v4.position;
-
- // copy vertex normals
- vec = out->mNormals = new aiVector3D[4];
- *vec++ = v1.normal;
- *vec++ = v2.normal;
- *vec++ = v3.normal;
- *vec = v4.normal;
-
- // copy texture coordinates
- vec = out->mTextureCoords[0] = new aiVector3D[4];
- *vec++ = v1.uv;
- *vec++ = v2.uv;
- *vec++ = v3.uv;
- *vec = v4.uv;
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::BuildSkybox(std::vector<aiMesh*>& meshes, std::vector<aiMaterial*> materials)
-{
- // Update the material of the skybox - replace the name and disable shading for skyboxes.
- for (unsigned int i = 0; i < 6;++i) {
- MaterialHelper* out = ( MaterialHelper* ) (*(materials.end()-(6-i)));
-
- aiString s;
- s.length = ::sprintf( s.data, "SkyboxSide_%i",i );
- out->AddProperty(&s,AI_MATKEY_NAME);
-
- int shading = aiShadingMode_NoShading;
- out->AddProperty(&shading,1,AI_MATKEY_SHADING_MODEL);
- }
-
- // Skyboxes are much more difficult. They are represented
- // by six single planes with different textures, so we'll
- // need to build six meshes.
-
- const float l = 10.f; // the size used by Irrlicht
-
- // FRONT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex(-l,-l,-l, 0, 0, 1, 1.f,1.f),
- SkyboxVertex( l,-l,-l, 0, 0, 1, 0.f,1.f),
- SkyboxVertex( l, l,-l, 0, 0, 1, 0.f,0.f),
- SkyboxVertex(-l, l,-l, 0, 0, 1, 1.f,0.f)) );
- meshes.back()->mMaterialIndex = materials.size()-6u;
-
- // LEFT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l,-l, -1, 0, 0, 1.f,1.f),
- SkyboxVertex( l,-l, l, -1, 0, 0, 0.f,1.f),
- SkyboxVertex( l, l, l, -1, 0, 0, 0.f,0.f),
- SkyboxVertex( l, l,-l, -1, 0, 0, 1.f,0.f)) );
- meshes.back()->mMaterialIndex = materials.size()-5u;
-
- // BACK SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l, l, 0, 0, -1, 1.f,1.f),
- SkyboxVertex(-l,-l, l, 0, 0, -1, 0.f,1.f),
- SkyboxVertex(-l, l, l, 0, 0, -1, 0.f,0.f),
- SkyboxVertex( l, l, l, 0, 0, -1, 1.f,0.f)) );
- meshes.back()->mMaterialIndex = materials.size()-4u;
-
- // RIGHT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex(-l,-l, l, 1, 0, 0, 1.f,1.f),
- SkyboxVertex(-l,-l,-l, 1, 0, 0, 0.f,1.f),
- SkyboxVertex(-l, l,-l, 1, 0, 0, 0.f,0.f),
- SkyboxVertex(-l, l, l, 1, 0, 0, 1.f,0.f)) );
- meshes.back()->mMaterialIndex = materials.size()-3u;
-
- // TOP SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l, l,-l, 0, -1, 0, 1.f,1.f),
- SkyboxVertex( l, l, l, 0, -1, 0, 0.f,1.f),
- SkyboxVertex(-l, l, l, 0, -1, 0, 0.f,0.f),
- SkyboxVertex(-l, l,-l, 0, -1, 0, 1.f,0.f)) );
- meshes.back()->mMaterialIndex = materials.size()-2u;
-
- // BOTTOM SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l, l, 0, 1, 0, 0.f,0.f),
- SkyboxVertex( l,-l,-l, 0, 1, 0, 1.f,0.f),
- SkyboxVertex(-l,-l,-l, 0, 1, 0, 1.f,1.f),
- SkyboxVertex(-l,-l, l, 0, 1, 0, 0.f,1.f)) );
- meshes.back()->mMaterialIndex = materials.size()-1u;
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::CopyMaterial(std::vector<aiMaterial*>& materials,
- std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
- unsigned int& defMatIdx,
- aiMesh* mesh)
-{
- if (inmaterials.empty()) {
- // Do we have a default material? If not we need to create one
- if (0xffffffff == defMatIdx)
- {
- defMatIdx = (unsigned int)materials.size();
- MaterialHelper* mat = new MaterialHelper();
-
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- aiColor3D c(0.6f,0.6f,0.6f);
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
- }
- mesh->mMaterialIndex = defMatIdx;
- return;
- }
- else if (inmaterials.size() > 1) {
- DefaultLogger::get()->info("IRR: Skipping additional materials");
- }
-
- mesh->mMaterialIndex = (unsigned int)materials.size();
- materials.push_back(inmaterials[0].first);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-inline int ClampSpline(int idx, int size)
-{
- return ( idx<0 ? size+idx : ( idx>=size ? idx-size : idx ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void FindSuitableMultiple(int& angle)
-{
- if (angle < 3)angle = 3;
- else if (angle < 10) angle = 10;
- else if (angle < 20) angle = 20;
- else if (angle < 30) angle = 30;
- else
- {
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNodeAnim*>& anims)
-{
- ai_assert(NULL != root && NULL != real);
-
- // XXX totally WIP - doesn't produce proper results, need to evaluate
- // whether there's any use for Irrlicht's proprietary scene format
- // outside Irrlicht ...
-
- if (root->animators.empty()) {
- return;
- }
- unsigned int total = 0;
- for (std::list<Animator>::iterator it = root->animators.begin();it != root->animators.end(); ++it) {
- if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER) {
- DefaultLogger::get()->warn("IRR: Skipping unknown or unsupported animator");
- continue;
- }
- ++total;
- }
- if (!total)return;
- else if (1 == total) {
- DefaultLogger::get()->warn("IRR: Adding dummy nodes to simulate multiple animators");
- }
-
- // NOTE: 1 tick == i millisecond
-
- unsigned int cur = 0;
- for (std::list<Animator>::iterator it = root->animators.begin();
- it != root->animators.end(); ++it)
- {
- if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER)continue;
-
- Animator& in = *it ;
- aiNodeAnim* anim = new aiNodeAnim();
-
- if (cur != total-1) {
- // Build a new name - a prefix instead of a suffix because it is
- // easier to check against
- anim->mNodeName.length = ::sprintf(anim->mNodeName.data,
- "$INST_DUMMY_%i_%s",total-1,
- (root->name.length() ? root->name.c_str() : ""));
-
- // we'll also need to insert a dummy in the node hierarchy.
- aiNode* dummy = new aiNode();
-
- for (unsigned int i = 0; i < real->mParent->mNumChildren;++i)
- if (real->mParent->mChildren[i] == real)
- real->mParent->mChildren[i] = dummy;
-
- dummy->mParent = real->mParent;
- dummy->mName = anim->mNodeName;
-
- dummy->mNumChildren = 1;
- dummy->mChildren = new aiNode*[dummy->mNumChildren];
- dummy->mChildren[0] = real;
-
- // the transformation matrix of the dummy node is the identity
-
- real->mParent = dummy;
- }
- else anim->mNodeName.Set(root->name);
- ++cur;
-
- switch (in.type) {
- case Animator::ROTATION:
- {
- // -----------------------------------------------------
- // find out how long a full rotation will take
- // This is the least common multiple of 360.f and all
- // three euler angles. Although we'll surely find a
- // possible multiple (haha) it could be somewhat large
- // for our purposes. So we need to modify the angles
- // here in order to get good results.
- // -----------------------------------------------------
- int angles[3];
- angles[0] = (int)(in.direction.x*100);
- angles[1] = (int)(in.direction.y*100);
- angles[2] = (int)(in.direction.z*100);
-
- angles[0] %= 360;
- angles[1] %= 360;
- angles[2] %= 360;
-
- if ((angles[0]*angles[1]) && (angles[1]*angles[2]))
- {
- FindSuitableMultiple(angles[0]);
- FindSuitableMultiple(angles[1]);
- FindSuitableMultiple(angles[2]);
- }
-
- int lcm = 360;
-
- if (angles[0])
- lcm = boost::math::lcm(lcm,angles[0]);
-
- if (angles[1])
- lcm = boost::math::lcm(lcm,angles[1]);
-
- if (angles[2])
- lcm = boost::math::lcm(lcm,angles[2]);
-
- if (360 == lcm)
- break;
-
-#if 0
- // This can be a division through zero, but we don't care
- float f1 = (float)lcm / angles[0];
- float f2 = (float)lcm / angles[1];
- float f3 = (float)lcm / angles[2];
-#endif
-
- // find out how many time units we'll need for the finest
- // track (in seconds) - this defines the number of output
- // keys (fps * seconds)
- float max = 0.f;
- if (angles[0])
- max = (float)lcm / angles[0];
- if (angles[1])
- max = std::max(max, (float)lcm / angles[1]);
- if (angles[2])
- max = std::max(max, (float)lcm / angles[2]);
-
- anim->mNumRotationKeys = (unsigned int)(max*fps);
- anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
-
- // begin with a zero angle
- aiVector3D angle;
- for (unsigned int i = 0; i < anim->mNumRotationKeys;++i)
- {
- // build the quaternion for the given euler angles
- aiQuatKey& q = anim->mRotationKeys[i];
-
- q.mValue = aiQuaternion(angle.x, angle.y, angle.z);
- q.mTime = (double)i;
-
- // increase the angle
- angle += in.direction;
- }
-
- // This animation is repeated and repeated ...
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- }
- break;
-
- case Animator::FLY_CIRCLE:
- {
- // -----------------------------------------------------
- // Find out how much time we'll need to perform a
- // full circle.
- // -----------------------------------------------------
- const double seconds = (1. / in.speed) / 1000.;
- const double tdelta = 1000. / fps;
-
- anim->mNumPositionKeys = (unsigned int) (fps * seconds);
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- // from Irrlicht, what else should we do than copying it?
- aiVector3D vecU,vecV;
- if (in.direction.y) {
- vecV = aiVector3D(50,0,0) ^ in.direction;
- }
- else vecV = aiVector3D(0,50,00) ^ in.direction;
- vecV.Normalize();
- vecU = (vecV ^ in.direction).Normalize();
-
- // build the output keys
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
- aiVectorKey& key = anim->mPositionKeys[i];
- key.mTime = i * tdelta;
-
- const float t = (float) ( in.speed * key.mTime );
- key.mValue = in.circleCenter + in.circleRadius * ((vecU*::cos(t)) + (vecV*::sin(t)));
- }
-
- // This animation is repeated and repeated ...
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- }
- break;
-
- case Animator::FLY_STRAIGHT:
- {
- anim->mPostState = anim->mPreState = (in.loop ? aiAnimBehaviour_REPEAT : aiAnimBehaviour_CONSTANT);
- const double seconds = in.timeForWay / 1000.;
- const double tdelta = 1000. / fps;
-
- anim->mNumPositionKeys = (unsigned int) (fps * seconds);
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- aiVector3D diff = in.direction - in.circleCenter;
- const float lengthOfWay = diff.Length();
- diff.Normalize();
-
- const double timeFactor = lengthOfWay / in.timeForWay;
-
- // build the output keys
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
- aiVectorKey& key = anim->mPositionKeys[i];
- key.mTime = i * tdelta;
- key.mValue = in.circleCenter + diff * float(timeFactor * key.mTime);
- }
- }
- break;
-
- case Animator::FOLLOW_SPLINE:
- {
- // repeat outside the defined time range
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- const int size = (int)in.splineKeys.size();
- if (!size) {
- // We have no point in the spline. That's bad. Really bad.
- DefaultLogger::get()->warn("IRR: Spline animators with no points defined");
-
- delete anim;anim = NULL;
- break;
- }
- else if (size == 1) {
- // We have just one point in the spline so we don't need the full calculation
- anim->mNumPositionKeys = 1;
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- anim->mPositionKeys[0].mValue = in.splineKeys[0].mValue;
- anim->mPositionKeys[0].mTime = 0.f;
- break;
- }
-
- unsigned int ticksPerFull = 15;
- anim->mNumPositionKeys = (unsigned int) ( ticksPerFull * fps );
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i)
- {
- aiVectorKey& key = anim->mPositionKeys[i];
-
- const float dt = (i * in.speed * 0.001f );
- const float u = dt - floor(dt);
- const int idx = (int)floor(dt) % size;
-
- // get the 4 current points to evaluate the spline
- const aiVector3D& p0 = in.splineKeys[ ClampSpline( idx - 1, size ) ].mValue;
- const aiVector3D& p1 = in.splineKeys[ ClampSpline( idx + 0, size ) ].mValue;
- const aiVector3D& p2 = in.splineKeys[ ClampSpline( idx + 1, size ) ].mValue;
- const aiVector3D& p3 = in.splineKeys[ ClampSpline( idx + 2, size ) ].mValue;
-
- // compute polynomials
- const float u2 = u*u;
- const float u3 = u2*2;
-
- const float h1 = 2.0f * u3 - 3.0f * u2 + 1.0f;
- const float h2 = -2.0f * u3 + 3.0f * u3;
- const float h3 = u3 - 2.0f * u3;
- const float h4 = u3 - u2;
-
- // compute the spline tangents
- const aiVector3D t1 = ( p2 - p0 ) * in.tightness;
- aiVector3D t2 = ( p3 - p1 ) * in.tightness;
-
- // and use them to get the interpolated point
- t2 = (h1 * p1 + p2 * h2 + t1 * h3 + h4 * t2);
-
- // build a simple translation matrix from it
- key.mValue = t2.x;
- key.mTime = (double) i;
- }
- }
- break;
- default:
- // UNKNOWN , OTHER
- break;
- };
- if (anim) {
- anims.push_back(anim);
- ++total;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// This function is maybe more generic than we'd need it here
-void SetupMapping (MaterialHelper* mat, aiTextureMapping mode, const aiVector3D& axis = aiVector3D(0.f,0.f,-1.f))
-{
- // Check whether there are texture properties defined - setup
- // the desired texture mapping mode for all of them and ignore
- // all UV settings we might encounter. WE HAVE NO UVS!
-
- std::vector<aiMaterialProperty*> p;
- p.reserve(mat->mNumProperties+1);
-
- for (unsigned int i = 0; i < mat->mNumProperties;++i)
- {
- aiMaterialProperty* prop = mat->mProperties[i];
- if (!::strcmp( prop->mKey.data, "$tex.file")) {
- // Setup the mapping key
- aiMaterialProperty* m = new aiMaterialProperty();
- m->mKey.Set("$tex.mapping");
- m->mIndex = prop->mIndex;
- m->mSemantic = prop->mSemantic;
- m->mType = aiPTI_Integer;
-
- m->mDataLength = 4;
- m->mData = new char[4];
- *((int*)m->mData) = mode;
-
- p.push_back(prop);
- p.push_back(m);
-
- // Setup the mapping axis
- if (mode == aiTextureMapping_CYLINDER || mode == aiTextureMapping_PLANE || mode == aiTextureMapping_SPHERE) {
- m = new aiMaterialProperty();
- m->mKey.Set("$tex.mapaxis");
- m->mIndex = prop->mIndex;
- m->mSemantic = prop->mSemantic;
- m->mType = aiPTI_Float;
-
- m->mDataLength = 12;
- m->mData = new char[12];
- *((aiVector3D*)m->mData) = axis;
- p.push_back(m);
- }
- }
- else if (! ::strcmp( prop->mKey.data, "$tex.uvwsrc")) {
- delete mat->mProperties[i];
- }
- else p.push_back(prop);
- }
-
- if (p.empty())return;
-
- // rebuild the output array
- if (p.size() > mat->mNumAllocated) {
- delete[] mat->mProperties;
- mat->mProperties = new aiMaterialProperty*[p.size()*2];
-
- mat->mNumAllocated = p.size()*2;
- }
- mat->mNumProperties = (unsigned int)p.size();
- ::memcpy(mat->mProperties,&p[0],sizeof(void*)*mat->mNumProperties);
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
- BatchLoader& batch,
- std::vector<aiMesh*>& meshes,
- std::vector<aiNodeAnim*>& anims,
- std::vector<AttachmentInfo>& attach,
- std::vector<aiMaterial*>& materials,
- unsigned int& defMatIdx)
-{
- unsigned int oldMeshSize = (unsigned int)meshes.size();
- //unsigned int meshTrafoAssign = 0;
-
- // Now determine the type of the node
- switch (root->type)
- {
- case Node::ANIMMESH:
- case Node::MESH:
- {
- if (!root->meshPath.length())
- break;
-
- // Get the loaded mesh from the scene and add it to
- // the list of all scenes to be attached to the
- // graph we're currently building
- aiScene* scene = batch.GetImport(root->id);
- if (!scene) {
- DefaultLogger::get()->error("IRR: Unable to load external file: " + root->meshPath);
- break;
- }
- attach.push_back(AttachmentInfo(scene,rootOut));
-
- // Now combine the material we've loaded for this mesh
- // with the real materials we got from the file. As we
- // don't execute any pp-steps on the file, the numbers
- // should be equal. If they are not, we can impossibly
- // do this ...
- if (root->materials.size() != (unsigned int)scene->mNumMaterials) {
- DefaultLogger::get()->warn("IRR: Failed to match imported materials "
- "with the materials found in the IRR scene file");
-
- break;
- }
- for (unsigned int i = 0; i < scene->mNumMaterials;++i) {
- // Delete the old material, we don't need it anymore
- delete scene->mMaterials[i];
-
- std::pair<aiMaterial*, unsigned int>& src = root->materials[i];
- scene->mMaterials[i] = src.first;
- }
-
- // NOTE: Each mesh should have exactly one material assigned,
- // but we do it in a separate loop if this behaviour changes
- // in future.
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- // Process material flags
- aiMesh* mesh = scene->mMeshes[i];
-
-
- // If "trans_vertex_alpha" mode is enabled, search all vertex colors
- // and check whether they have a common alpha value. This is quite
- // often the case so we can simply extract it to a shared oacity
- // value.
- std::pair<aiMaterial*, unsigned int>& src = root->materials[mesh->mMaterialIndex];
- MaterialHelper* mat = (MaterialHelper*)src.first;
-
- if (mesh->HasVertexColors(0) && src.second & AI_IRRMESH_MAT_trans_vertex_alpha)
- {
- bool bdo = true;
- for (unsigned int a = 1; a < mesh->mNumVertices;++a) {
-
- if (mesh->mColors[0][a].a != mesh->mColors[0][a-1].a) {
- bdo = false;
- break;
- }
- }
- if (bdo) {
- DefaultLogger::get()->info("IRR: Replacing mesh vertex alpha with common opacity");
-
- for (unsigned int a = 0; a < mesh->mNumVertices;++a)
- mesh->mColors[0][a].a = 1.f;
-
- mat->AddProperty(& mesh->mColors[0][0].a, 1, AI_MATKEY_OPACITY);
- }
- }
-
- // If we have a second texture coordinate set and a second texture
- // (either lightmap, normalmap, 2layered material) we need to
- // setup the correct UV index for it. The texture can either
- // be diffuse (lightmap & 2layer) or a normal map (normal & parallax)
- if (mesh->HasTextureCoords(1)) {
-
- int idx = 1;
- if (src.second & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
- }
- else if (src.second & AI_IRRMESH_MAT_normalmap_solid) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0));
- }
- }
- }
- }
- break;
-
- case Node::LIGHT:
- case Node::CAMERA:
-
- // We're already finished with lights and cameras
- break;
-
-
- case Node::SPHERE:
- {
- // Generate the sphere model. Our input parameter to
- // the sphere generation algorithm is the number of
- // subdivisions of each triangle - but here we have
- // the number of poylgons on a specific axis. Just
- // use some hardcoded limits to approximate this ...
- unsigned int mul = root->spherePolyCountX*root->spherePolyCountY;
- if (mul < 100)mul = 2;
- else if (mul < 300)mul = 3;
- else mul = 4;
-
- meshes.push_back(StandardShapes::MakeMesh(mul,
- &StandardShapes::MakeSphere));
-
- // Adjust scaling
- root->scaling *= root->sphereRadius/2;
-
- // Copy one output material
- CopyMaterial(materials, root->materials, defMatIdx, meshes.back());
-
- // Now adjust this output material - if there is a first texture
- // set, setup spherical UV mapping around the Y axis.
- SetupMapping ( (MaterialHelper*) materials.back(), aiTextureMapping_SPHERE);
- }
- break;
-
- case Node::CUBE:
- {
- // Generate an unit cube first
- meshes.push_back(StandardShapes::MakeMesh(
- &StandardShapes::MakeHexahedron));
-
- // Adjust scaling
- root->scaling *= root->sphereRadius;
-
- // Copy one output material
- CopyMaterial(materials, root->materials, defMatIdx, meshes.back());
-
- // Now adjust this output material - if there is a first texture
- // set, setup cubic UV mapping
- SetupMapping ( (MaterialHelper*) materials.back(), aiTextureMapping_BOX );
- }
- break;
-
-
- case Node::SKYBOX:
- {
- // A skybox is defined by six materials
- if (root->materials.size() < 6) {
- DefaultLogger::get()->error("IRR: There should be six materials for a skybox");
- break;
- }
-
- // copy those materials and generate 6 meshes for our new skybox
- materials.reserve(materials.size() + 6);
- for (unsigned int i = 0; i < 6;++i)
- materials.insert(materials.end(),root->materials[i].first);
-
- BuildSkybox(meshes,materials);
-
- // *************************************************************
- // Skyboxes will require a different code path for rendering,
- // so there must be a way for the user to add special support
- // for IRR skyboxes. We add a 'IRR.SkyBox_' prefix to the node.
- // *************************************************************
- root->name = "IRR.SkyBox_" + root->name;
- DefaultLogger::get()->info("IRR: Loading skybox, this will "
- "require special handling to be displayed correctly");
- }
- break;
-
- case Node::TERRAIN:
- {
- // to support terrains, we'd need to have a texture decoder
- DefaultLogger::get()->error("IRR: Unsupported node - TERRAIN");
- }
- break;
- default:
- // DUMMY
- break;
- };
-
- // Check whether we added a mesh (or more than one ...). In this case
- // we'll also need to attach it to the node
- if (oldMeshSize != (unsigned int) meshes.size()) {
-
- rootOut->mNumMeshes = (unsigned int)meshes.size() - oldMeshSize;
- rootOut->mMeshes = new unsigned int[rootOut->mNumMeshes];
-
- for (unsigned int a = 0; a < rootOut->mNumMeshes;++a) {
- rootOut->mMeshes[a] = oldMeshSize+a;
- }
- }
-
- // Setup the name of this node
- rootOut->mName.Set(root->name);
-
- // Now compute the final local transformation matrix of the
- // node from the given translation, rotation and scaling values.
- // (the rotation is given in Euler angles, XYZ order)
- //std::swap((float&)root->rotation.z,(float&)root->rotation.y);
- rootOut->mTransformation.FromEulerAnglesXYZ(AI_DEG_TO_RAD(root->rotation) );
-
- // apply scaling
- aiMatrix4x4& mat = rootOut->mTransformation;
- mat.a1 *= root->scaling.x;
- mat.b1 *= root->scaling.x;
- mat.c1 *= root->scaling.x;
- mat.a2 *= root->scaling.y;
- mat.b2 *= root->scaling.y;
- mat.c2 *= root->scaling.y;
- mat.a3 *= root->scaling.z;
- mat.b3 *= root->scaling.z;
- mat.c3 *= root->scaling.z;
-
- // apply translation
- mat.a4 += root->position.x;
- mat.b4 += root->position.y;
- mat.c4 += root->position.z;
-
- // now compute animations for the node
- ComputeAnimations(root,rootOut, anims);
-
- // Add all children recursively. First allocate enough storage
- // for them, then call us again
- rootOut->mNumChildren = (unsigned int)root->children.size();
- if (rootOut->mNumChildren) {
-
- rootOut->mChildren = new aiNode*[rootOut->mNumChildren];
- for (unsigned int i = 0; i < rootOut->mNumChildren;++i) {
-
- aiNode* node = rootOut->mChildren[i] = new aiNode();
- node->mParent = rootOut;
- GenerateGraph(root->children[i],node,scene,batch,meshes,
- anims,attach,materials,defMatIdx);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void IRRImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open IRR file " + pFile + "");
-
- // Construct the irrXML parser
- CIrrXML_IOStreamReader st(file.get());
- reader = createIrrXMLReader((IFileReadCallBack*) &st);
-
- // The root node of the scene
- Node* root = new Node(Node::DUMMY);
- root->parent = NULL;
- root->name = "<IRRSceneRoot>";
-
- // Current node parent
- Node* curParent = root;
-
- // Scenegraph node we're currently working on
- Node* curNode = NULL;
-
- // List of output cameras
- std::vector<aiCamera*> cameras;
-
- // List of output lights
- std::vector<aiLight*> lights;
-
- // Batch loader used to load external models
- BatchLoader batch(pIOHandler);
-// batch.SetBasePath(pFile);
-
- cameras.reserve(5);
- lights.reserve(5);
-
- bool inMaterials = false, inAnimator = false;
- unsigned int guessedAnimCnt = 0, guessedMeshCnt = 0, guessedMatCnt = 0;
-
- // Parse the XML file
- while (reader->read()) {
- switch (reader->getNodeType()) {
- case EXN_ELEMENT:
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
- // ***********************************************************************
- /* What we're going to do with the node depends
- * on its type:
- *
- * "mesh" - Load a mesh from an external file
- * "cube" - Generate a cube
- * "skybox" - Generate a skybox
- * "light" - A light source
- * "sphere" - Generate a sphere mesh
- * "animatedMesh" - Load an animated mesh from an external file
- * and join its animation channels with ours.
- * "empty" - A dummy node
- * "camera" - A camera
- * "terrain" - a terrain node (data comes from a heightmap)
- * "billboard", ""
- *
- * Each of these nodes can be animated and all can have multiple
- * materials assigned (except lights, cameras and dummies, of course).
- */
- // ***********************************************************************
- const char* sz = reader->getAttributeValueSafe("type");
- Node* nd;
- if (!ASSIMP_stricmp(sz,"mesh") || !ASSIMP_stricmp(sz,"octTree")) {
- // OctTree's and meshes are treated equally
- nd = new Node(Node::MESH);
- }
- else if (!ASSIMP_stricmp(sz,"cube")) {
- nd = new Node(Node::CUBE);
- ++guessedMeshCnt;
- // meshes.push_back(StandardShapes::MakeMesh(&StandardShapes::MakeHexahedron));
- }
- else if (!ASSIMP_stricmp(sz,"skybox")) {
- nd = new Node(Node::SKYBOX);
- guessedMeshCnt += 6;
- }
- else if (!ASSIMP_stricmp(sz,"camera")) {
- nd = new Node(Node::CAMERA);
-
- // Setup a temporary name for the camera
- aiCamera* cam = new aiCamera();
- cam->mName.Set( nd->name );
- cameras.push_back(cam);
- }
- else if (!ASSIMP_stricmp(sz,"light")) {
- nd = new Node(Node::LIGHT);
-
- // Setup a temporary name for the light
- aiLight* cam = new aiLight();
- cam->mName.Set( nd->name );
- lights.push_back(cam);
- }
- else if (!ASSIMP_stricmp(sz,"sphere")) {
- nd = new Node(Node::SPHERE);
- ++guessedMeshCnt;
- }
- else if (!ASSIMP_stricmp(sz,"animatedMesh")) {
- nd = new Node(Node::ANIMMESH);
- }
- else if (!ASSIMP_stricmp(sz,"empty")) {
- nd = new Node(Node::DUMMY);
- }
- else if (!ASSIMP_stricmp(sz,"terrain")) {
- nd = new Node(Node::TERRAIN);
- }
- else if (!ASSIMP_stricmp(sz,"billBoard")) {
- // We don't support billboards, so ignore them
- DefaultLogger::get()->error("IRR: Billboards are not supported by Assimp");
- nd = new Node(Node::DUMMY);
- }
- else {
- DefaultLogger::get()->warn("IRR: Found unknown node: " + std::string(sz));
-
- /* We skip the contents of nodes we don't know.
- * We parse the transformation and all animators
- * and skip the rest.
- */
- nd = new Node(Node::DUMMY);
- }
-
- /* Attach the newly created node to the scenegraph
- */
- curNode = nd;
- nd->parent = curParent;
- curParent->children.push_back(nd);
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
- inMaterials = true;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
- inAnimator = true;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
- /* We should have a valid node here
- * FIX: no ... the scene root node is also contained in an attributes block
- */
- if (!curNode) {
-#if 0
- DefaultLogger::get()->error("IRR: Encountered <attributes> element, but "
- "there is no node active");
-#endif
- continue;
- }
-
- Animator* curAnim = NULL;
-
- // Materials can occur for nearly any type of node
- if (inMaterials && curNode->type != Node::DUMMY) {
- /* This is a material description - parse it!
- */
- curNode->materials.push_back(std::pair< aiMaterial*, unsigned int > () );
- std::pair< aiMaterial*, unsigned int >& p = curNode->materials.back();
-
- p.first = ParseMaterial(p.second);
-
- ++guessedMatCnt;
- continue;
- }
- else if (inAnimator) {
- /* This is an animation path - add a new animator
- * to the list.
- */
- curNode->animators.push_back(Animator());
- curAnim = & curNode->animators.back();
-
- ++guessedAnimCnt;
- }
-
- /* Parse all elements in the attributes block
- * and process them.
- */
- while (reader->read()) {
- if (reader->getNodeType() == EXN_ELEMENT) {
- if (!ASSIMP_stricmp(reader->getNodeName(),"vector3d")) {
- VectorProperty prop;
- ReadVectorProperty(prop);
-
- if (inAnimator) {
- if (curAnim->type == Animator::ROTATION && prop.name == "Rotation") {
- // We store the rotation euler angles in 'direction'
- curAnim->direction = prop.value;
- }
- else if (curAnim->type == Animator::FOLLOW_SPLINE) {
- // Check whether the vector follows the PointN naming scheme,
- // here N is the ONE-based index of the point
- if (prop.name.length() >= 6 && prop.name.substr(0,5) == "Point") {
- // Add a new key to the list
- curAnim->splineKeys.push_back(aiVectorKey());
- aiVectorKey& key = curAnim->splineKeys.back();
-
- // and parse its properties
- key.mValue = prop.value;
- key.mTime = strtol10(&prop.name[5]);
- }
- }
- else if (curAnim->type == Animator::FLY_CIRCLE) {
- if (prop.name == "Center") {
- curAnim->circleCenter = prop.value;
- }
- else if (prop.name == "Direction") {
- curAnim->direction = prop.value;
-
- // From Irrlicht's source - a workaround for backward compatibility with Irrlicht 1.1
- if (curAnim->direction == aiVector3D()) {
- curAnim->direction = aiVector3D(0.f,1.f,0.f);
- }
- else curAnim->direction.Normalize();
- }
- }
- else if (curAnim->type == Animator::FLY_STRAIGHT) {
- if (prop.name == "Start") {
- // We reuse the field here
- curAnim->circleCenter = prop.value;
- }
- else if (prop.name == "End") {
- // We reuse the field here
- curAnim->direction = prop.value;
- }
- }
- }
- else {
- if (prop.name == "Position") {
- curNode->position = prop.value;
- }
- else if (prop.name == "Rotation") {
- curNode->rotation = prop.value;
- }
- else if (prop.name == "Scale") {
- curNode->scaling = prop.value;
- }
- else if (Node::CAMERA == curNode->type)
- {
- aiCamera* cam = cameras.back();
- if (prop.name == "Target") {
- cam->mLookAt = prop.value;
- }
- else if (prop.name == "UpVector") {
- cam->mUp = prop.value;
- }
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"bool")) {
- BoolProperty prop;
- ReadBoolProperty(prop);
-
- if (inAnimator && curAnim->type == Animator::FLY_CIRCLE && prop.name == "Loop") {
- curAnim->loop = prop.value;
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"float")) {
- FloatProperty prop;
- ReadFloatProperty(prop);
-
- if (inAnimator) {
- // The speed property exists for several animators
- if (prop.name == "Speed") {
- curAnim->speed = prop.value;
- }
- else if (curAnim->type == Animator::FLY_CIRCLE && prop.name == "Radius") {
- curAnim->circleRadius = prop.value;
- }
- else if (curAnim->type == Animator::FOLLOW_SPLINE && prop.name == "Tightness") {
- curAnim->tightness = prop.value;
- }
- }
- else {
- if (prop.name == "FramesPerSecond" && Node::ANIMMESH == curNode->type) {
- curNode->framesPerSecond = prop.value;
- }
- else if (Node::CAMERA == curNode->type) {
- /* This is the vertical, not the horizontal FOV.
- * We need to compute the right FOV from the
- * screen aspect which we don't know yet.
- */
- if (prop.name == "Fovy") {
- cameras.back()->mHorizontalFOV = prop.value;
- }
- else if (prop.name == "Aspect") {
- cameras.back()->mAspect = prop.value;
- }
- else if (prop.name == "ZNear") {
- cameras.back()->mClipPlaneNear = prop.value;
- }
- else if (prop.name == "ZFar") {
- cameras.back()->mClipPlaneFar = prop.value;
- }
- }
- else if (Node::LIGHT == curNode->type) {
- /* Additional light information
- */
- if (prop.name == "Attenuation") {
- lights.back()->mAttenuationLinear = prop.value;
- }
- else if (prop.name == "OuterCone") {
- lights.back()->mAngleOuterCone = AI_DEG_TO_RAD( prop.value );
- }
- else if (prop.name == "InnerCone") {
- lights.back()->mAngleInnerCone = AI_DEG_TO_RAD( prop.value );
- }
- }
- // radius of the sphere to be generated -
- // or alternatively, size of the cube
- else if ((Node::SPHERE == curNode->type && prop.name == "Radius")
- || (Node::CUBE == curNode->type && prop.name == "Size" )) {
-
- curNode->sphereRadius = prop.value;
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"int")) {
- IntProperty prop;
- ReadIntProperty(prop);
-
- if (inAnimator) {
- if (curAnim->type == Animator::FLY_STRAIGHT && prop.name == "TimeForWay") {
- curAnim->timeForWay = prop.value;
- }
- }
- else {
- // sphere polgon numbers in each direction
- if (Node::SPHERE == curNode->type) {
-
- if (prop.name == "PolyCountX") {
- curNode->spherePolyCountX = prop.value;
- }
- else if (prop.name == "PolyCountY") {
- curNode->spherePolyCountY = prop.value;
- }
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"string") ||!ASSIMP_stricmp(reader->getNodeName(),"enum")) {
- StringProperty prop;
- ReadStringProperty(prop);
- if (prop.value.length()) {
- if (prop.name == "Name") {
- curNode->name = prop.value;
-
- /* If we're either a camera or a light source
- * we need to update the name in the aiLight/
- * aiCamera structure, too.
- */
- if (Node::CAMERA == curNode->type) {
- cameras.back()->mName.Set(prop.value);
- }
- else if (Node::LIGHT == curNode->type) {
- lights.back()->mName.Set(prop.value);
- }
- }
- else if (Node::LIGHT == curNode->type && "LightType" == prop.name)
- {
- if (prop.value == "Spot")
- lights.back()->mType = aiLightSource_SPOT;
- else if (prop.value == "Point")
- lights.back()->mType = aiLightSource_POINT;
- else if (prop.value == "Directional")
- lights.back()->mType = aiLightSource_DIRECTIONAL;
- else
- {
- // We won't pass the validation with aiLightSourceType_UNDEFINED,
- // so we remove the light and replace it with a silly dummy node
- delete lights.back();
- lights.pop_back();
- curNode->type = Node::DUMMY;
-
- DefaultLogger::get()->error("Ignoring light of unknown type: " + prop.value);
- }
- }
- else if ((prop.name == "Mesh" && Node::MESH == curNode->type) ||
- Node::ANIMMESH == curNode->type)
- {
- /* This is the file name of the mesh - either
- * animated or not. We need to make sure we setup
- * the correct postprocessing settings here.
- */
- unsigned int pp = 0;
- BatchLoader::PropertyMap map;
-
- /* If the mesh is a static one remove all animations from the impor data
- */
- if (Node::ANIMMESH != curNode->type) {
- pp |= aiProcess_RemoveComponent;
- SetGenericProperty<int>(map.ints,AI_CONFIG_PP_RVC_FLAGS,
- aiComponent_ANIMATIONS | aiComponent_BONEWEIGHTS);
- }
-
- /* TODO: maybe implement the protection against recursive
- * loading calls directly in BatchLoader? The current
- * implementation is not absolutely safe. A LWS and an IRR
- * file referencing each other *could* cause the system to
- * recurse forever.
- */
-
- const std::string extension = GetExtension(prop.value);
- if ("irr" == extension) {
- DefaultLogger::get()->error("IRR: Can't load another IRR file recursively");
- }
- else
- {
- curNode->id = batch.AddLoadRequest(prop.value,pp,&map);
- curNode->meshPath = prop.value;
- }
- }
- else if (inAnimator && prop.name == "Type")
- {
- // type of the animator
- if (prop.value == "rotation") {
- curAnim->type = Animator::ROTATION;
- }
- else if (prop.value == "flyCircle") {
- curAnim->type = Animator::FLY_CIRCLE;
- }
- else if (prop.value == "flyStraight") {
- curAnim->type = Animator::FLY_CIRCLE;
- }
- else if (prop.value == "followSpline") {
- curAnim->type = Animator::FOLLOW_SPLINE;
- }
- else {
- DefaultLogger::get()->warn("IRR: Ignoring unknown animator: "
- + prop.value);
-
- curAnim->type = Animator::UNKNOWN;
- }
- }
- }
- }
- }
- else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
- break;
- }
- }
- }
- break;
-
- case EXN_ELEMENT_END:
-
- // If we reached the end of a node, we need to continue processing its parent
- if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
- if (!curNode) {
- // currently is no node set. We need to go
- // back in the node hierarchy
- if (!curParent) {
- curParent = root;
- DefaultLogger::get()->error("IRR: Too many closing <node> elements");
- }
- else curParent = curParent->parent;
- }
- else curNode = NULL;
- }
- // clear all flags
- else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
- inMaterials = false;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
- inAnimator = false;
- }
- break;
-
- default:
- // GCC complains that not all enumeration values are handled
- break;
- }
- }
-
- /* Now iterate through all cameras and compute their final (horizontal) FOV
- */
- for (std::vector<aiCamera*>::iterator it = cameras.begin(), end = cameras.end();it != end; ++it) {
- aiCamera* cam = *it;
-
- // screen aspect could be missing
- if (cam->mAspect) {
- cam->mHorizontalFOV *= cam->mAspect;
- }
- else DefaultLogger::get()->warn("IRR: Camera aspect is not given, can't compute horizontal FOV");
- }
-
- batch.LoadAll();
-
- /* Allocate a tempoary scene data structure
- */
- aiScene* tempScene = new aiScene();
- tempScene->mRootNode = new aiNode();
- tempScene->mRootNode->mName.Set("<IRRRoot>");
-
- /* Copy the cameras to the output array
- */
- if (!cameras.empty()) {
- tempScene->mNumCameras = (unsigned int)cameras.size();
- tempScene->mCameras = new aiCamera*[tempScene->mNumCameras];
- ::memcpy(tempScene->mCameras,&cameras[0],sizeof(void*)*tempScene->mNumCameras);
- }
-
- /* Copy the light sources to the output array
- */
- if (!lights.empty()) {
- tempScene->mNumLights = (unsigned int)lights.size();
- tempScene->mLights = new aiLight*[tempScene->mNumLights];
- ::memcpy(tempScene->mLights,&lights[0],sizeof(void*)*tempScene->mNumLights);
- }
-
- // temporary data
- std::vector< aiNodeAnim*> anims;
- std::vector< aiMaterial*> materials;
- std::vector< AttachmentInfo > attach;
- std::vector<aiMesh*> meshes;
-
- // try to guess how much storage we'll need
- anims.reserve (guessedAnimCnt + (guessedAnimCnt >> 2));
- meshes.reserve (guessedMeshCnt + (guessedMeshCnt >> 2));
- materials.reserve (guessedMatCnt + (guessedMatCnt >> 2));
-
- /* Now process our scenegraph recursively: generate final
- * meshes and generate animation channels for all nodes.
- */
- unsigned int defMatIdx = 0xffffffff;
- GenerateGraph(root,tempScene->mRootNode, tempScene,
- batch, meshes, anims, attach, materials, defMatIdx);
-
- if (!anims.empty())
- {
- tempScene->mNumAnimations = 1;
- tempScene->mAnimations = new aiAnimation*[tempScene->mNumAnimations];
- aiAnimation* an = tempScene->mAnimations[0] = new aiAnimation();
-
- // ***********************************************************
- // This is only the global animation channel of the scene.
- // If there are animated models, they will have separate
- // animation channels in the scene. To display IRR scenes
- // correctly, users will need to combine the global anim
- // channel with all the local animations they want to play
- // ***********************************************************
- an->mName.Set("Irr_GlobalAnimChannel");
-
- // copy all node animation channels to the global channel
- an->mNumChannels = (unsigned int)anims.size();
- an->mChannels = new aiNodeAnim*[an->mNumChannels];
- ::memcpy(an->mChannels, & anims [0], sizeof(void*)*an->mNumChannels);
- }
- if (!meshes.empty()) {
- // copy all meshes to the temporary scene
- tempScene->mNumMeshes = (unsigned int)meshes.size();
- tempScene->mMeshes = new aiMesh*[tempScene->mNumMeshes];
- ::memcpy(tempScene->mMeshes,&meshes[0],tempScene->mNumMeshes*
- sizeof(void*));
- }
-
- /* Copy all materials to the output array
- */
- if (!materials.empty()) {
- tempScene->mNumMaterials = (unsigned int)materials.size();
- tempScene->mMaterials = new aiMaterial*[tempScene->mNumMaterials];
- ::memcpy(tempScene->mMaterials,&materials[0],sizeof(void*)*
- tempScene->mNumMaterials);
- }
-
- /* Now merge all sub scenes and attach them to the correct
- * attachment points in the scenegraph.
- */
- SceneCombiner::MergeScenes(&pScene,tempScene,attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
-
-
- /* If we have no meshes | no materials now set the INCOMPLETE
- * scene flag. This is necessary if we failed to load all
- * models from external files
- */
- if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
- DefaultLogger::get()->warn("IRR: No meshes loaded, setting AI_SCENE_FLAGS_INCOMPLETE");
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- /* Finished ... everything destructs automatically and all
- * temporary scenes have already been deleted by MergeScenes()
- */
- return;
-}
diff --git a/3rdparty/assimp/code/IRRLoader.h b/3rdparty/assimp/code/IRRLoader.h
deleted file mode 100644
index 569d59db..00000000
--- a/3rdparty/assimp/code/IRRLoader.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file IRRLoader.h
- * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
- * importer class.
- */
-#ifndef AI_IRRLOADER_H_INCLUDED
-#define AI_IRRLOADER_H_INCLUDED
-
-#include "IRRShared.h"
-#include "SceneCombiner.h"
-
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** Irr importer class.
- *
- * Irr is the native scene file format of the Irrlight engine and its editor
- * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
- * it might be a good file format for data exchange.
- */
-class IRRImporter : public BaseImporter, public IrrlichtBase
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- IRRImporter();
-
- /** Destructor, private as well */
- ~IRRImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /**
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /**
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /**
- */
- void SetupProperties(const Importer* pImp);
-
-private:
-
- /** Data structure for a scenegraph node animator
- */
- struct Animator
- {
- // Type of the animator
- enum AT
- {
- UNKNOWN = 0x0,
- ROTATION = 0x1,
- FLY_CIRCLE = 0x2,
- FLY_STRAIGHT = 0x3,
- FOLLOW_SPLINE = 0x4,
- OTHER = 0x5
-
- } type;
-
- Animator(AT t = UNKNOWN)
- : type (t)
- , speed (0.001f)
- , direction (0.f,1.f,0.f)
- , circleRadius (1.f)
- , tightness (0.5f)
- , loop (true)
- , timeForWay (100)
- {
- }
-
-
- // common parameters
- float speed;
- aiVector3D direction;
-
- // FLY_CIRCLE
- aiVector3D circleCenter;
- float circleRadius;
-
- // FOLLOW_SPLINE
- float tightness;
- std::vector<aiVectorKey> splineKeys;
-
- // ROTATION (angles given in direction)
-
- // FLY STRAIGHT
- // circleCenter = start, direction = end
- bool loop;
- int timeForWay;
- };
-
- /** Data structure for a scenegraph node in an IRR file
- */
- struct Node
- {
- // Type of the node
- enum ET
- {
- LIGHT,
- CUBE,
- MESH,
- SKYBOX,
- DUMMY,
- CAMERA,
- TERRAIN,
- SPHERE,
- ANIMMESH
- } type;
-
- Node(ET t)
- : type (t)
- , scaling (1.f,1.f,1.f) // assume uniform scaling by default
- , framesPerSecond (0.f)
- , sphereRadius (1.f)
- , spherePolyCountX (100)
- , spherePolyCountY (100)
- {
-
- // Generate a default name for the node
- char buffer[128];
- static int cnt;
- ::sprintf(buffer,"IrrNode_%i",cnt++);
- name = std::string(buffer);
-
- // reserve space for up to 5 materials
- materials.reserve(5);
-
- // reserve space for up to 5 children
- children.reserve(5);
- }
-
- // Transformation of the node
- aiVector3D position, rotation, scaling;
-
- // Name of the node
- std::string name;
-
- // List of all child nodes
- std::vector<Node*> children;
-
- // Parent node
- Node* parent;
-
- // Animated meshes: frames per second
- // 0.f if not specified
- float framesPerSecond;
-
- // Meshes: path to the mesh to be loaded
- std::string meshPath;
- unsigned int id;
-
- // Meshes: List of materials to be assigned
- // along with their corresponding material flags
- std::vector< std::pair<aiMaterial*, unsigned int> > materials;
-
- // Spheres: radius of the sphere to be generates
- float sphereRadius;
-
- // Spheres: Number of polygons in the x,y direction
- unsigned int spherePolyCountX,spherePolyCountY;
-
- // List of all animators assigned to the node
- std::list<Animator> animators;
- };
-
- /** Data structure for a vertex in an IRR skybox
- */
- struct SkyboxVertex
- {
- SkyboxVertex()
- {}
-
- //! Construction from single vertex components
- SkyboxVertex(float px, float py, float pz,
- float nx, float ny, float nz,
- float uvx, float uvy)
-
- : position (px,py,pz)
- , normal (nx,ny,nz)
- , uv (uvx,uvy,0.f)
- {}
-
- aiVector3D position, normal, uv;
- };
-
-
- // -------------------------------------------------------------------
- /** Fill the scenegraph recursively
- */
- void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
- BatchLoader& batch,
- std::vector<aiMesh*>& meshes,
- std::vector<aiNodeAnim*>& anims,
- std::vector<AttachmentInfo>& attach,
- std::vector<aiMaterial*>& materials,
- unsigned int& defaultMatIdx);
-
-
- // -------------------------------------------------------------------
- /** Generate a mesh that consists of just a single quad
- */
- aiMesh* BuildSingleQuadMesh(const SkyboxVertex& v1,
- const SkyboxVertex& v2,
- const SkyboxVertex& v3,
- const SkyboxVertex& v4);
-
-
- // -------------------------------------------------------------------
- /** Build a skybox
- *
- * @param meshes Receives 6 output meshes
- * @param materials The last 6 materials are assigned to the newly
- * created meshes. The names of the materials are adjusted.
- */
- void BuildSkybox(std::vector<aiMesh*>& meshes,
- std::vector<aiMaterial*> materials);
-
-
- // -------------------------------------------------------------------
- /** Copy a material for a mesh to the output material list
- *
- * @param materials Receives an output material
- * @param inmaterials List of input materials
- * @param defMatIdx Default material index - 0xffffffff if not there
- * @param mesh Mesh to work on
- */
- void CopyMaterial(std::vector<aiMaterial*>& materials,
- std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
- unsigned int& defMatIdx,
- aiMesh* mesh);
-
-
- // -------------------------------------------------------------------
- /** Compute animations for a specific node
- *
- * @param root Node to be processed
- * @param anims The list of output animations
- */
- void ComputeAnimations(Node* root, aiNode* real,
- std::vector<aiNodeAnim*>& anims);
-
-
-private:
-
- /** Configuration option: desired output FPS */
- double fps;
-
- /** Configuration option: speed flag was set? */
- bool configSpeedFlag;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IRRIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/IRRMeshLoader.cpp b/3rdparty/assimp/code/IRRMeshLoader.cpp
deleted file mode 100644
index 69e29a5b..00000000
--- a/3rdparty/assimp/code/IRRMeshLoader.cpp
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the IrrMesh importer class */
-
-#include "AssimpPCH.h"
-
-#include "IRRMeshLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IRRMeshImporter::IRRMeshImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IRRMeshImporter::~IRRMeshImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- /* NOTE: A simple check for the file extension is not enough
- * here. Irrmesh and irr are easy, but xml is too generic
- * and could be collada, too. So we need to open the file and
- * search for typical tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "irrmesh")return true;
- else if (extension == "xml" || checkSig)
- {
- /* If CanRead() is called to check whether the loader
- * supports a specific file extension in general we
- * must return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"irrmesh"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all file extensions which are handled by this class
-void IRRMeshImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("xml");
- extensions.insert("irrmesh");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void IRRMeshImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open IRRMESH file " + pFile + "");
-
- // Construct the irrXML parser
- CIrrXML_IOStreamReader st(file.get());
- reader = createIrrXMLReader((IFileReadCallBack*) &st);
-
- // final data
- std::vector<aiMaterial*> materials;
- std::vector<aiMesh*> meshes;
- materials.reserve (5);
- meshes.reserve (5);
-
- // temporary data - current mesh buffer
- aiMaterial* curMat = NULL;
- aiMesh* curMesh = NULL;
- unsigned int curMatFlags;
-
- std::vector<aiVector3D> curVertices,curNormals,curTangents,curBitangents;
- std::vector<aiColor4D> curColors;
- std::vector<aiVector3D> curUVs,curUV2s;
-
- // some temporary variables
- int textMeaning = 0;
- int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
- bool useColors = false;
-
- // Parse the XML file
- while (reader->read()) {
- switch (reader->getNodeType()) {
- case EXN_ELEMENT:
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) {
- // end of previous buffer. A material and a mesh should be there
- if ( !curMat || !curMesh) {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- delete curMat;
- delete curMesh;
- }
- else {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- curMat = NULL;
- curMesh = NULL;
-
- curVertices.clear();
- curColors.clear();
- curNormals.clear();
- curUV2s.clear();
- curUVs.clear();
- curTangents.clear();
- curBitangents.clear();
- }
-
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"material")) {
- if (curMat) {
- DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please");
- delete curMat;curMat = NULL;
- }
- curMat = ParseMaterial(curMatFlags);
- }
- /* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices"))
- {
- int num = reader->getAttributeValueAsInt("vertexCount");
-
- if (!num) {
- // This is possible ... remove the mesh from the list and skip further reading
- DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices");
-
- delete curMat;curMat = NULL;
-
- curMesh = NULL;
- textMeaning = 0;
- continue;
- }
-
- curVertices.reserve (num);
- curNormals.reserve (num);
- curColors.reserve (num);
- curUVs.reserve (num);
-
- // Determine the file format
- const char* t = reader->getAttributeValueSafe("type");
- if (!ASSIMP_stricmp("2tcoords", t)) {
- curUV2s.reserve (num);
- vertexFormat = 1;
-
- if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) {
- // *********************************************************
- // We have a second texture! So use this UV channel
- // for it. The 2nd texture can be either a normal
- // texture (solid_2layer or lightmap_xxx) or a normal
- // map (normal_..., parallax_...)
- // *********************************************************
- int idx = 1;
- MaterialHelper* mat = ( MaterialHelper* ) curMat;
-
- if (curMatFlags & AI_IRRMESH_MAT_lightmap){
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_LIGHTMAP(0));
- }
- else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid){
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0));
- }
- else if (curMatFlags & AI_IRRMESH_MAT_solid_2layer) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
- }
- }
- }
- else if (!ASSIMP_stricmp("tangents", t)) {
- curTangents.reserve (num);
- curBitangents.reserve (num);
- vertexFormat = 2;
- }
- else if (ASSIMP_stricmp("standard", t)) {
- delete curMat;
- DefaultLogger::get()->warn("IRRMESH: Unknown vertex format");
- }
- else vertexFormat = 0;
- textMeaning = 1;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"indices")) {
- if (curVertices.empty() && curMat) {
- delete curMat;
- throw DeadlyImportError("IRRMESH: indices must come after vertices");
- }
-
- textMeaning = 2;
-
- // start a new mesh
- curMesh = new aiMesh();
-
- // allocate storage for all faces
- curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
- if (!curMesh->mNumVertices) {
- // This is possible ... remove the mesh from the list and skip further reading
- DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices");
-
- // mesh - away
- delete curMesh; curMesh = NULL;
-
- // material - away
- delete curMat;curMat = NULL;
-
- textMeaning = 0;
- continue;
- }
-
- if (curMesh->mNumVertices % 3) {
- DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3");
- }
-
- curMesh->mNumFaces = curMesh->mNumVertices / 3;
- curMesh->mFaces = new aiFace[curMesh->mNumFaces];
-
- // setup some members
- curMesh->mMaterialIndex = (unsigned int)materials.size();
- curMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for all vertices
- curMesh->mVertices = new aiVector3D[curMesh->mNumVertices];
-
- if (curNormals.size() == curVertices.size()) {
- curMesh->mNormals = new aiVector3D[curMesh->mNumVertices];
- }
- if (curTangents.size() == curVertices.size()) {
- curMesh->mTangents = new aiVector3D[curMesh->mNumVertices];
- }
- if (curBitangents.size() == curVertices.size()) {
- curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices];
- }
- if (curColors.size() == curVertices.size() && useColors) {
- curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices];
- }
- if (curUVs.size() == curVertices.size()) {
- curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices];
- }
- if (curUV2s.size() == curVertices.size()) {
- curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices];
- }
- }
- break;
-
- case EXN_TEXT:
- {
- const char* sz = reader->getNodeData();
- if (textMeaning == 1) {
- textMeaning = 0;
-
- // read vertices
- do {
- SkipSpacesAndLineEnd(&sz);
- aiVector3D temp;aiColor4D c;
-
- // Read the vertex position
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- curVertices.push_back(temp);
-
- // Read the vertex normals
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- curNormals.push_back(temp);
-
- // read the vertex colors
- uint32_t clr = strtol16(sz,&sz);
- ColorFromARGBPacked(clr,c);
-
- if (!curColors.empty() && c != *(curColors.end()-1))
- useColors = true;
-
- curColors.push_back(c);
- SkipSpaces(&sz);
-
-
- // read the first UV coordinate set
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.z = 0.f;
- temp.y = 1.f - temp.y; // DX to OGL
- curUVs.push_back(temp);
-
- // read the (optional) second UV coordinate set
- if (vertexFormat == 1) {
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- temp.y = 1.f - temp.y; // DX to OGL
- curUV2s.push_back(temp);
- }
- // read optional tangent and bitangent vectors
- else if (vertexFormat == 2) {
- // tangents
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curTangents.push_back(temp);
-
- // bitangents
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
-
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curBitangents.push_back(temp);
- }
- }
-
- /* IMPORTANT: We assume that each vertex is specified in one
- line. So we can skip the rest of the line - unknown vertex
- elements are ignored.
- */
-
- while (SkipLine(&sz));
- }
- else if (textMeaning == 2) {
- textMeaning = 0;
-
- // read indices
- aiFace* curFace = curMesh->mFaces;
- aiFace* const faceEnd = curMesh->mFaces + curMesh->mNumFaces;
-
- aiVector3D* pcV = curMesh->mVertices;
- aiVector3D* pcN = curMesh->mNormals;
- aiVector3D* pcT = curMesh->mTangents;
- aiVector3D* pcB = curMesh->mBitangents;
- aiColor4D* pcC0 = curMesh->mColors[0];
- aiVector3D* pcT0 = curMesh->mTextureCoords[0];
- aiVector3D* pcT1 = curMesh->mTextureCoords[1];
-
- unsigned int curIdx = 0;
- unsigned int total = 0;
- while (SkipSpacesAndLineEnd(&sz)) {
- if (curFace >= faceEnd) {
- DefaultLogger::get()->error("IRRMESH: Too many indices");
- break;
- }
- if (!curIdx) {
- curFace->mNumIndices = 3;
- curFace->mIndices = new unsigned int[3];
- }
-
- unsigned int idx = strtol10(sz,&sz);
- if (idx >= curVertices.size()) {
- DefaultLogger::get()->error("IRRMESH: Index out of range");
- idx = 0;
- }
-
- curFace->mIndices[curIdx] = total++;
-
- *pcV++ = curVertices[idx];
- if (pcN)*pcN++ = curNormals[idx];
- if (pcT)*pcT++ = curTangents[idx];
- if (pcB)*pcB++ = curBitangents[idx];
- if (pcC0)*pcC0++ = curColors[idx];
- if (pcT0)*pcT0++ = curUVs[idx];
- if (pcT1)*pcT1++ = curUV2s[idx];
-
- if (++curIdx == 3) {
- ++curFace;
- curIdx = 0;
- }
- }
-
- if (curFace != faceEnd)
- DefaultLogger::get()->error("IRRMESH: Not enough indices");
-
- // Finish processing the mesh - do some small material workarounds
- if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
- // Take the opacity value of the current material
- // from the common vertex color alpha
- MaterialHelper* mat = (MaterialHelper*)curMat;
- mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
- }
- }}
- break;
-
- default:
-
- // GCC complains here ...
- break;
-
- };
- }
-
- // End of the last buffer. A material and a mesh should be there
- if (curMat || curMesh) {
- if ( !curMat || !curMesh) {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- delete curMat;
- delete curMesh;
- }
- else {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- }
-
- if (materials.empty())
- throw DeadlyImportError("IRRMESH: Unable to read a mesh from this file");
-
-
- // now generate the output scene
- pScene->mNumMeshes = (unsigned int)meshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- pScene->mMeshes[i] = meshes[i];
-
- // clean this value ...
- pScene->mMeshes[i]->mNumUVComponents[3] = 0;
- }
-
- pScene->mNumMaterials = (unsigned int)materials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- ::memcpy(pScene->mMaterials,&materials[0],sizeof(void*)*pScene->mNumMaterials);
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<IRRMesh>");
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- // clean up and return
- delete reader;
- AI_DEBUG_INVALIDATE_PTR(reader);
-}
diff --git a/3rdparty/assimp/code/IRRMeshLoader.h b/3rdparty/assimp/code/IRRMeshLoader.h
deleted file mode 100644
index 06dde833..00000000
--- a/3rdparty/assimp/code/IRRMeshLoader.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file IRRMeshLoader.h
- * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
- * importer class.
- */
-#ifndef AI_IRRMESHLOADER_H_INCLUDED
-#define AI_IRRMESHLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "IRRShared.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** IrrMesh importer class.
- *
- * IrrMesh is the native file format of the Irrlight engine and its editor
- * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
- * it might be a good file format for data exchange.
- */
-class IRRMeshImporter : public BaseImporter, public IrrlichtBase
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- IRRMeshImporter();
-
- /** Destructor, private as well */
- ~IRRMeshImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IRRMESHIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/IRRShared.cpp b/3rdparty/assimp/code/IRRShared.cpp
deleted file mode 100644
index 89aced7a..00000000
--- a/3rdparty/assimp/code/IRRShared.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file IRRShared.cpp
- * @brief Shared utilities for the IRR and IRRMESH loaders
- */
-
-#include "AssimpPCH.h"
-
-#include "IRRShared.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-// Transformation matrix to convert from Assimp to IRR space
-const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
-// ------------------------------------------------------------------------------------------------
-// read a property in hexadecimal format (i.e. ffffffff)
-void IrrlichtBase::ReadHexProperty (HexProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the hexadecimal value
- out.value = strtol16(reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a decimal property
-void IrrlichtBase::ReadIntProperty (IntProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the ecimal value
- out.value = strtol10s(reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a string property
-void IrrlichtBase::ReadStringProperty (StringProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // simple copy the string
- out.value = std::string (reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a boolean property
-void IrrlichtBase::ReadBoolProperty (BoolProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // true or false, case insensitive
- out.value = (ASSIMP_stricmp( reader->getAttributeValue(i),
- "true") ? false : true);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a float property
-void IrrlichtBase::ReadFloatProperty (FloatProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // just parse the float
- out.value = fast_atof( reader->getAttributeValue(i) );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a vector property
-void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // three floats, separated with commas
- const char* ptr = reader->getAttributeValue(i);
-
- SkipSpaces(&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.x );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.y );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.z );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a string to a proper aiMappingMode
-int ConvertMappingMode(const std::string& mode)
-{
- if (mode == "texture_clamp_repeat")
- {
- return aiTextureMapMode_Wrap;
- }
- else if (mode == "texture_clamp_mirror")
- return aiTextureMapMode_Mirror;
-
- return aiTextureMapMode_Clamp;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a material from the XML file
-aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
-{
- MaterialHelper* mat = new MaterialHelper();
- aiColor4D clr;
- aiString s;
-
- matFlags = 0; // zero output flags
- int cnt = 0; // number of used texture channels
- unsigned int nd = 0;
-
- // Continue reading from the file
- while (reader->read())
- {
- switch (reader->getNodeType())
- {
- case EXN_ELEMENT:
-
- // Hex properties
- if (!ASSIMP_stricmp(reader->getNodeName(),"color"))
- {
- HexProperty prop;
- ReadHexProperty(prop);
- if (prop.name == "Diffuse")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- }
- else if (prop.name == "Ambient")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
- }
- else if (prop.name == "Specular")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
- }
-
- // NOTE: The 'emissive' property causes problems. It is
- // often != 0, even if there is obviously no light
- // emitted by the described surface. In fact I think
- // IRRLICHT ignores this property, too.
-#if 0
- else if (prop.name == "Emissive")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
- }
-#endif
- }
- // Float properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
- {
- FloatProperty prop;
- ReadFloatProperty(prop);
- if (prop.name == "Shininess")
- {
- mat->AddProperty(&prop.value,1,AI_MATKEY_SHININESS);
- }
- }
- // Bool properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"bool"))
- {
- BoolProperty prop;
- ReadBoolProperty(prop);
- if (prop.name == "Wireframe")
- {
- int val = (prop.value ? true : false);
- mat->AddProperty(&val,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
- else if (prop.name == "GouraudShading")
- {
- int val = (prop.value ? aiShadingMode_Gouraud
- : aiShadingMode_NoShading);
- mat->AddProperty(&val,1,AI_MATKEY_SHADING_MODEL);
- }
- else if (prop.name == "BackfaceCulling")
- {
- int val = (!prop.value);
- mat->AddProperty(&val,1,AI_MATKEY_TWOSIDED);
- }
- }
- // String properties - textures and texture related properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"texture") ||
- !ASSIMP_stricmp(reader->getNodeName(),"enum"))
- {
- StringProperty prop;
- ReadStringProperty(prop);
- if (prop.value.length())
- {
- // material type (shader)
- if (prop.name == "Type")
- {
- if (prop.value == "solid")
- {
- // default material ...
- }
- else if (prop.value == "trans_vertex_alpha")
- {
- matFlags = AI_IRRMESH_MAT_trans_vertex_alpha;
- }
- else if (prop.value == "lightmap")
- {
- matFlags = AI_IRRMESH_MAT_lightmap;
- }
- else if (prop.value == "solid_2layer")
- {
- matFlags = AI_IRRMESH_MAT_solid_2layer;
- }
- else if (prop.value == "lightmap_m2")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m2;
- }
- else if (prop.value == "lightmap_m4")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m4;
- }
- else if (prop.value == "lightmap_light")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light;
- }
- else if (prop.value == "lightmap_light_m2")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light_m2;
- }
- else if (prop.value == "lightmap_light_m4")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light_m4;
- }
- else if (prop.value == "lightmap_add")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_add;
- }
- // Normal and parallax maps are treated equally
- else if (prop.value == "normalmap_solid" ||
- prop.value == "parallaxmap_solid")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_solid;
- }
- else if (prop.value == "normalmap_trans_vertex_alpha" ||
- prop.value == "parallaxmap_trans_vertex_alpha")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_tva;
- }
- else if (prop.value == "normalmap_trans_add" ||
- prop.value == "parallaxmap_trans_add")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_ta;
- }
- else {
- DefaultLogger::get()->warn("IRRMat: Unrecognized material type: " + prop.value);
- }
- }
-
- // Up to 4 texture channels are supported
- if (prop.name == "Texture1")
- {
- // Always accept the primary texture channel
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else if (prop.name == "Texture2" && cnt == 1)
- {
- // 2-layer material lightmapped?
- if (matFlags & AI_IRRMESH_MAT_lightmap) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_LIGHTMAP(0));
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- // alternatively: normal or parallax mapping
- else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_NORMALS(0));
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- // or just as second diffuse texture
- else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1));
- ++nd;
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- else DefaultLogger::get()->warn("IRRmat: Skipping second texture");
- }
-
- else if (prop.name == "Texture3" && cnt == 2)
- {
- // Irrlicht does not seem to use these channels.
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+1));
- }
- else if (prop.name == "Texture4" && cnt == 3)
- {
- // Irrlicht does not seem to use these channels.
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+2));
- }
-
- // Texture mapping options
- if (prop.name == "TextureWrap1" && cnt >= 1)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
- }
- else if (prop.name == "TextureWrap2" && cnt >= 2)
- {
- int map = ConvertMappingMode(prop.value);
- if (matFlags & AI_IRRMESH_MAT_lightmap) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(0));
- }
- else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_NORMALS(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_NORMALS(0));
- }
- else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(1));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(1));
- }
- }
- else if (prop.name == "TextureWrap3" && cnt >= 3)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd+1));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd+1));
- }
- else if (prop.name == "TextureWrap4" && cnt >= 4)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd+2));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd+2));
- }
- }
- }
- break;
- case EXN_ELEMENT_END:
-
- /* Assume there are no further nested nodes in <material> elements
- */
- if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") ||
- /* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes"))
- {
- // Now process lightmapping flags
- // We should have at least one textur to do that ..
- if (cnt && matFlags & AI_IRRMESH_MAT_lightmap)
- {
- float f = 1.f;
- unsigned int unmasked = matFlags&~AI_IRRMESH_MAT_lightmap;
-
- // Additive lightmap?
- int op = (unmasked & AI_IRRMESH_MAT_lightmap_add
- ? aiTextureOp_Add : aiTextureOp_Multiply);
-
- // Handle Irrlicht's lightmapping scaling factor
- if (unmasked & AI_IRRMESH_MAT_lightmap_m2 ||
- unmasked & AI_IRRMESH_MAT_lightmap_light_m2)
- {
- f = 2.f;
- }
- else if (unmasked & AI_IRRMESH_MAT_lightmap_m4 ||
- unmasked & AI_IRRMESH_MAT_lightmap_light_m4)
- {
- f = 4.f;
- }
- mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_LIGHTMAP(0));
- mat->AddProperty( &op,1, AI_MATKEY_TEXOP_LIGHTMAP(0));
- }
-
- return mat;
- }
- default:
-
- // GCC complains here ...
- break;
- }
- }
- DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete");
- return mat;
-}
diff --git a/3rdparty/assimp/code/IRRShared.h b/3rdparty/assimp/code/IRRShared.h
deleted file mode 100644
index 03e0c78b..00000000
--- a/3rdparty/assimp/code/IRRShared.h
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-/** @file IRRShared.h
- * @brief Shared utilities for the IRR and IRRMESH loaders
- */
-
-#ifndef INCLUDED_AI_IRRSHARED_H
-#define INCLUDED_AI_IRRSHARED_H
-
-#include "irrXMLWrapper.h"
-#include "BaseImporter.h"
-
-namespace Assimp {
-
-
-/** @brief Matrix to convert from Assimp to IRR and backwards
- */
-extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
-
-
-// Default: 0 = solid, one texture
-#define AI_IRRMESH_MAT_solid_2layer 0x10000
-
-// Transparency flags
-#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1
-#define AI_IRRMESH_MAT_trans_add 0x2
-
-// Lightmapping flags
-#define AI_IRRMESH_MAT_lightmap 0x2
-#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4)
-#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x8)
-#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap|0x10)
-#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap|0x20)
-#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap|0x40)
-#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap|0x80)
-
-// Standard NormalMap (or Parallax map, they're treated equally)
-#define AI_IRRMESH_MAT_normalmap_solid (0x100)
-
-// Normal map combined with vertex alpha
-#define AI_IRRMESH_MAT_normalmap_tva \
- (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha)
-
-// Normal map combined with additive transparency
-#define AI_IRRMESH_MAT_normalmap_ta \
- (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add)
-
-// Special flag. It indicates a second texture has been found
-// Its type depends ... either a normal textue or a normal map
-#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000
-
-// ---------------------------------------------------------------------------
-/** Base class for the Irr and IrrMesh importers.
- *
- * Declares some irrlight-related xml parsing utilities and provides tools
- * to load materials from IRR and IRRMESH files.
- */
-class IrrlichtBase
-{
-protected:
-
- /** @brief Data structure for a simple name-value property
- */
- template <class T>
- struct Property
- {
- std::string name;
- T value;
- };
-
- typedef Property<uint32_t> HexProperty;
- typedef Property<std::string> StringProperty;
- typedef Property<bool> BoolProperty;
- typedef Property<float> FloatProperty;
- typedef Property<aiVector3D> VectorProperty;
- typedef Property<int> IntProperty;
-
- /** XML reader instance
- */
- irr::io::IrrXMLReader* reader;
-
- // -------------------------------------------------------------------
- /** Parse a material description from the XML
- * @return The created material
- * @param matFlags Receives AI_IRRMESH_MAT_XX flags
- */
- aiMaterial* ParseMaterial(unsigned int& matFlags);
-
- // -------------------------------------------------------------------
- /** Read a property of the specified type from the current XML element.
- * @param out Recives output data
- */
- void ReadHexProperty (HexProperty& out);
- void ReadStringProperty (StringProperty& out);
- void ReadBoolProperty (BoolProperty& out);
- void ReadFloatProperty (FloatProperty& out);
- void ReadVectorProperty (VectorProperty& out);
- void ReadIntProperty (IntProperty& out);
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Unpack a hex color, e.g. 0xdcdedfff
-inline void ColorFromARGBPacked(uint32_t in, aiColor4D& clr)
-{
- clr.a = ((in >> 24) & 0xff) / 255.f;
- clr.r = ((in >> 16) & 0xff) / 255.f;
- clr.g = ((in >> 8) & 0xff) / 255.f;
- clr.b = ((in ) & 0xff) / 255.f;
-}
-
-
-} // end namespace Assimp
-
-#endif // !! INCLUDED_AI_IRRSHARED_H
diff --git a/3rdparty/assimp/code/Importer.cpp b/3rdparty/assimp/code/Importer.cpp
deleted file mode 100644
index 72204950..00000000
--- a/3rdparty/assimp/code/Importer.cpp
+++ /dev/null
@@ -1,1415 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Importer.cpp
- * @brief Implementation of the CPP-API class #Importer
- */
-
-#include "AssimpPCH.h"
-#include "../include/aiVersion.h"
-
-// ------------------------------------------------------------------------------------------------
-/* Uncomment this line to prevent Assimp from catching unknown exceptions.
- *
- * Note that any Exception except DeadlyImportError may lead to
- * undefined behaviour -> loaders could remain in an unusable state and
- * further imports with the same Importer instance could fail/crash/burn ...
- */
-// ------------------------------------------------------------------------------------------------
-#define ASSIMP_CATCH_GLOBAL_EXCEPTIONS
-
-
-// ------------------------------------------------------------------------------------------------
-// Internal headers
-// ------------------------------------------------------------------------------------------------
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-#include "DefaultIOStream.h"
-#include "DefaultIOSystem.h"
-#include "DefaultProgressHandler.h"
-#include "GenericProperty.h"
-#include "ProcessHelper.h"
-#include "ScenePreprocessor.h"
-#include "MemoryIOWrapper.h"
-#include "Profiler.h"
-#include "TinyFormatter.h"
-
-using namespace Assimp::Profiling;
-using namespace Assimp::Formatter;
-
-// ------------------------------------------------------------------------------------------------
-// Importers
-// (include_new_importers_here)
-// ------------------------------------------------------------------------------------------------
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-# include "XFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-# include "3DSLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-# include "MD3Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-# include "MDLLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
-# include "MD2Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-# include "PlyLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-# include "ASELoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-# include "ObjFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-# include "HMPLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-# include "SMDLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-# include "MDCLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-# include "MD5Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-# include "STLLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-# include "LWOLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-# include "DXFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-# include "NFFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-# include "RawLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-# include "OFFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-# include "ACLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
-# include "BVHLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-# include "IRRMeshLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
-# include "IRRLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-# include "Q3DLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-# include "B3DImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-# include "ColladaLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-# include "TerragenLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-# include "CSMLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-# include "UnrealLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
-# include "LWSLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-# include "OgreImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-# include "MS3DLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-# include "COBLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-# include "BlenderLoader.h"
-#endif
-//#ifndef ASSIMP_BUILD_NO_SWORDOFMOONLIGHT_IMPORTER
-//# include "SomLoader.h"
-//#endif
-#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-# include "Q3BSPFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
-# include "NDOLoader.h"
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Post processing-Steps
-// ------------------------------------------------------------------------------------------------
-#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
-# include "CalcTangentsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-# include "JoinVerticesProcess.h"
-#endif
-#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
-# include "ConvertToLHProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-# include "TriangulateProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
-# include "GenFaceNormalsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
-# include "GenVertexNormalsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
-# include "RemoveVCProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
-# include "SplitLargeMeshes.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
-# include "PretransformVertices.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
-# include "LimitBoneWeightsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
-# include "ImproveCacheLocality.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
-# include "FixNormalsStep.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
-# include "RemoveRedundantMaterials.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-# include "FindInvalidDataProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
-# include "FindDegenerates.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
-# include "SortByPTypeProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
-# include "ComputeUVMappingProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
-# include "TextureTransform.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
-# include "FindInstancesProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-# include "OptimizeMeshes.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-# include "OptimizeGraph.h"
-#endif
-
-using namespace Assimp;
-using namespace Assimp::Intern;
-
-// ------------------------------------------------------------------------------------------------
-// Intern::AllocateFromAssimpHeap serves as abstract base class. It overrides
-// new and delete (and their array counterparts) of public API classes (e.g. Logger) to
-// utilize our DLL heap.
-// See http://www.gotw.ca/publications/mill15.htm
-// ------------------------------------------------------------------------------------------------
-void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) {
- return ::operator new(num_bytes);
-}
-
-void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() {
- try {
- return AllocateFromAssimpHeap::operator new( num_bytes );
- }
- catch( ... ) {
- return NULL;
- }
-}
-
-void AllocateFromAssimpHeap::operator delete ( void* data) {
- return ::operator delete(data);
-}
-
-void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) {
- return ::operator new[](num_bytes);
-}
-
-void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() {
- try {
- return AllocateFromAssimpHeap::operator new[]( num_bytes );
- }
- catch( ... ) {
- return NULL;
- }
-}
-
-void AllocateFromAssimpHeap::operator delete[] ( void* data) {
- return ::operator delete[](data);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer constructor.
-Importer::Importer()
-{
- // allocate the pimpl first
- pimpl = new ImporterPimpl();
-
- pimpl->mScene = NULL;
- pimpl->mErrorString = "";
-
- // Allocate a default IO handler
- pimpl->mIOHandler = new DefaultIOSystem;
- pimpl->mIsDefaultHandler = true;
- pimpl->bExtraVerbose = false; // disable extra verbose mode by default
-
- pimpl->mProgressHandler = new DefaultProgressHandler();
- pimpl->mIsDefaultProgressHandler = true;
-
- // ----------------------------------------------------------------------------
- // Add an instance of each worker class here
- // (register_new_importers_here)
- // ----------------------------------------------------------------------------
- pimpl->mImporter.reserve(64);
-#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
- pimpl->mImporter.push_back( new XFileImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
- pimpl->mImporter.push_back( new ObjFileImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
- pimpl->mImporter.push_back( new Discreet3DSImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
- pimpl->mImporter.push_back( new MD3Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
- pimpl->mImporter.push_back( new MD2Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
- pimpl->mImporter.push_back( new PLYImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
- pimpl->mImporter.push_back( new MDLImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
- pimpl->mImporter.push_back( new ASEImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
- pimpl->mImporter.push_back( new HMPImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
- pimpl->mImporter.push_back( new SMDImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
- pimpl->mImporter.push_back( new MDCImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
- pimpl->mImporter.push_back( new MD5Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
- pimpl->mImporter.push_back( new STLImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
- pimpl->mImporter.push_back( new LWOImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
- pimpl->mImporter.push_back( new DXFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
- pimpl->mImporter.push_back( new NFFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
- pimpl->mImporter.push_back( new RAWImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
- pimpl->mImporter.push_back( new OFFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
- pimpl->mImporter.push_back( new AC3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
- pimpl->mImporter.push_back( new BVHLoader());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
- pimpl->mImporter.push_back( new IRRMeshImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
- pimpl->mImporter.push_back( new IRRImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
- pimpl->mImporter.push_back( new Q3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
- pimpl->mImporter.push_back( new B3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
- pimpl->mImporter.push_back( new ColladaLoader());
-#endif
-#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
- pimpl->mImporter.push_back( new TerragenImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
- pimpl->mImporter.push_back( new CSMImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
- pimpl->mImporter.push_back( new UnrealImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
- pimpl->mImporter.push_back( new LWSImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
- pimpl->mImporter.push_back( new Ogre::OgreImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
- pimpl->mImporter.push_back( new MS3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
- pimpl->mImporter.push_back( new COBImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
- pimpl->mImporter.push_back( new BlenderImporter());
-#endif
-//#if (!defined ASSIMP_BUILD_NO_SWORDOFMOONLIGHT_IMPORTER)
-// pimpl->mImporter.push_back( new SomImporter());
-//#endif
-#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
- pimpl->mImporter.push_back( new Q3BSPFileImporter() );
-#endif
-#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
- pimpl->mImporter.push_back( new NDOImporter() );
-#endif
-
- // ----------------------------------------------------------------------------
- // Add an instance of each post processing step here in the order
- // of sequence it is executed. Steps that are added here are not
- // validated - as RegisterPPStep() does - all dependencies must be given.
- // ----------------------------------------------------------------------------
- pimpl->mPostProcessingSteps.reserve(25);
-#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new RemoveVCProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new RemoveRedundantMatsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FindInstancesProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new OptimizeGraphProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new OptimizeMeshesProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FindDegeneratesProcess());
-#endif
-#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
- pimpl->mPostProcessingSteps.push_back( new ComputeUVMappingProcess());
-#endif
-#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
- pimpl->mPostProcessingSteps.push_back( new TextureTransformStep());
-#endif
-#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new PretransformVertices());
-#endif
-#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new TriangulateProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new SortByPTypeProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FindInvalidDataProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FixInfacingNormalsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Triangle());
-#endif
-#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
-#endif
-
- // .........................................................................
- // DON'T change the order of these five!
- pimpl->mPostProcessingSteps.push_back( new ComputeSpatialSortProcess());
- // .........................................................................
-
-#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new GenVertexNormalsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new CalcTangentsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new JoinVerticesProcess());
-#endif
-
- // .........................................................................
- pimpl->mPostProcessingSteps.push_back( new DestroySpatialSortProcess());
- // .........................................................................
-
-#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new MakeLeftHandedProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FlipUVsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new FlipWindingOrderProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new LimitBoneWeightsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
- pimpl->mPostProcessingSteps.push_back( new ImproveCacheLocalityProcess());
-#endif
-
- // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list.
- pimpl->mPPShared = new SharedPostProcessInfo();
- for (std::vector<BaseProcess*>::iterator it = pimpl->mPostProcessingSteps.begin();
- it != pimpl->mPostProcessingSteps.end();
- ++it) {
-
- (*it)->SetSharedData(pimpl->mPPShared);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor of Importer
-Importer::~Importer()
-{
- // Delete all import plugins
- for ( unsigned int a = 0; a < pimpl->mImporter.size(); a++)
- delete pimpl->mImporter[a];
-
- // Delete all post-processing plug-ins
- for ( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
- delete pimpl->mPostProcessingSteps[a];
-
- // Delete the assigned IO handler
- delete pimpl->mIOHandler;
-
- // Kill imported scene. Destructors should do that recursivly
- delete pimpl->mScene;
-
- // Delete shared post-processing data
- delete pimpl->mPPShared;
-
- // and finally the pimpl itself
- delete pimpl;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy constructor - copies the config of another Importer, not the scene
-Importer::Importer(const Importer &other)
-{
- new(this) Importer();
-
- pimpl->mIntProperties = other.pimpl->mIntProperties;
- pimpl->mFloatProperties = other.pimpl->mFloatProperties;
- pimpl->mStringProperties = other.pimpl->mStringProperties;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Register a custom post-processing step
-aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
-{
- ai_assert(NULL != pImp);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- pimpl->mPostProcessingSteps.push_back(pImp);
- DefaultLogger::get()->info("Registering custom post-processing step");
-
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Register a custom loader plugin
-aiReturn Importer::RegisterLoader(BaseImporter* pImp)
-{
- ai_assert(NULL != pImp);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // --------------------------------------------------------------------
- // Check whether we would have two loaders for the same file extension
- // This is absolutely OK, but we should warn the developer of the new
- // loader that his code will probably never be called if the first
- // loader is a bit too lazy in his file checking.
- // --------------------------------------------------------------------
- std::set<std::string> st;
- std::string baked;
- pImp->GetExtensionList(st);
-
- for (std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) {
-
-#ifdef _DEBUG
- if (IsExtensionSupported(*it)) {
- DefaultLogger::get()->warn("The file extension " + *it + " is already in use");
- }
-#endif
- baked += *it;
- }
-
- // add the loader
- pimpl->mImporter.push_back(pImp);
- DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked);
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unregister a custom loader plugin
-aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
-{
- if (!pImp) {
- // unregistering a NULL importer is no problem for us ... really!
- return AI_SUCCESS;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),
- pimpl->mImporter.end(),pImp);
-
- if (it != pimpl->mImporter.end()) {
- pimpl->mImporter.erase(it);
-
- std::set<std::string> st;
- pImp->GetExtensionList(st);
-
- DefaultLogger::get()->info("Unregistering custom importer: ");
- return AI_SUCCESS;
- }
- DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ...");
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unregister a custom loader plugin
-aiReturn Importer::UnregisterPPStep(BaseProcess* pImp)
-{
- if (!pImp) {
- // unregistering a NULL ppstep is no problem for us ... really!
- return AI_SUCCESS;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(),
- pimpl->mPostProcessingSteps.end(),pImp);
-
- if (it != pimpl->mPostProcessingSteps.end()) {
- pimpl->mPostProcessingSteps.erase(it);
- DefaultLogger::get()->info("Unregistering custom post-processing step");
- return AI_SUCCESS;
- }
- DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you ..");
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Supplies a custom IO handler to the importer to open and access files.
-void Importer::SetIOHandler( IOSystem* pIOHandler)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // If the new handler is zero, allocate a default IO implementation.
- if (!pIOHandler)
- {
- // Release pointer in the possession of the caller
- pimpl->mIOHandler = new DefaultIOSystem();
- pimpl->mIsDefaultHandler = true;
- }
- // Otherwise register the custom handler
- else if (pimpl->mIOHandler != pIOHandler)
- {
- delete pimpl->mIOHandler;
- pimpl->mIOHandler = pIOHandler;
- pimpl->mIsDefaultHandler = false;
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the currently set IO handler
-IOSystem* Importer::GetIOHandler() const
-{
- return pimpl->mIOHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a custom IO handler is currently set
-bool Importer::IsDefaultIOHandler() const
-{
- return pimpl->mIsDefaultHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Supplies a custom progress handler to get regular callbacks during importing
-void Importer::SetProgressHandler ( ProgressHandler* pHandler )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // If the new handler is zero, allocate a default implementation.
- if (!pHandler)
- {
- // Release pointer in the possession of the caller
- pimpl->mProgressHandler = new DefaultProgressHandler();
- pimpl->mIsDefaultProgressHandler = true;
- }
- // Otherwise register the custom handler
- else if (pimpl->mProgressHandler != pHandler)
- {
- delete pimpl->mProgressHandler;
- pimpl->mProgressHandler = pHandler;
- pimpl->mIsDefaultProgressHandler = false;
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the currently set progress handler
-ProgressHandler* Importer::GetProgressHandler() const
-{
- return pimpl->mProgressHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a custom progress handler is currently set
-bool Importer::IsDefaultProgressHandler() const
-{
- return pimpl->mIsDefaultProgressHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate post process step flags
-bool _ValidateFlags(unsigned int pFlags)
-{
- if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) {
- DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
- return false;
- }
- if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) {
- DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible");
- return false;
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Free the current scene
-void Importer::FreeScene( )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- delete pimpl->mScene;
- pimpl->mScene = NULL;
-
- pimpl->mErrorString = "";
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the current error string, if any
-const char* Importer::GetErrorString() const
-{
- /* Must remain valid as long as ReadFile() or FreeFile() are not called */
- return pimpl->mErrorString.c_str();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Enable extra-verbose mode
-void Importer::SetExtraVerbose(bool bDo)
-{
- pimpl->bExtraVerbose = bDo;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the current scene
-const aiScene* Importer::GetScene() const
-{
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Orphan the current scene and return it.
-aiScene* Importer::GetOrphanedScene()
-{
- aiScene* s = pimpl->mScene;
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- pimpl->mScene = NULL;
-
- pimpl->mErrorString = ""; /* reset error string */
- ASSIMP_END_EXCEPTION_REGION(aiScene*);
- return s;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate post-processing flags
-bool Importer::ValidateFlags(unsigned int pFlags) const
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // run basic checks for mutually exclusive flags
- if (!_ValidateFlags(pFlags)) {
- return false;
- }
-
- // ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ...
-#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- if (pFlags & aiProcess_ValidateDataStructure) {
- return false;
- }
-#endif
- pFlags &= ~aiProcess_ValidateDataStructure;
-
- // Now iterate through all bits which are set in the flags and check whether we find at least
- // one pp plugin which handles it.
- for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) {
-
- if (pFlags & mask) {
-
- bool have = false;
- for ( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
- if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) {
-
- have = true;
- break;
- }
- }
- if (!have) {
- return false;
- }
- }
- }
- ASSIMP_END_EXCEPTION_REGION(bool);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
- size_t pLength,
- unsigned int pFlags,
- const char* pHint /*= ""*/)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- if (!pHint) {
- pHint = "";
- }
-
- if (!pBuffer || !pLength || strlen(pHint) > 100) {
- pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
- return NULL;
- }
-
- // prevent deletion of the previous IOHandler
- IOSystem* io = pimpl->mIOHandler;
- pimpl->mIOHandler = NULL;
-
- SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
-
- // read the file and recover the previous IOSystem
- char fbuff[128];
- sprintf(fbuff,"%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
-
- ReadFile(fbuff,pFlags);
- SetIOHandler(io);
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-void WriteLogOpening(const std::string& file)
-{
- Logger* l = DefaultLogger::get();
- if (!l) {
- return;
- }
- l->info("Load " + file);
-
- // print a full version dump. This is nice because we don't
- // need to ask the authors of incoming bug reports for
- // the library version they're using - a log dump is
- // sufficient.
- const unsigned int flags = aiGetCompileFlags();
- l->debug(format()
- << "Assimp "
- << aiGetVersionMajor()
- << "."
- << aiGetVersionMinor()
- << "."
- << aiGetVersionRevision()
-
-#if defined(ASSIMP_BUILD_X86_32BIT_ARCHITECTURE)
- << " x86"
-#elif defined(ASSIMP_BUILD_X86_64BIT_ARCHITECTURE)
- << " amd64"
-#elif defined(ASSIMP_BUILD_IA_64BIT_ARCHITECTURE)
- << " itanium"
-#elif defined(ASSIMP_BUILD_PPC_32BIT_ARCHITECTURE)
- << " ppc32"
-#elif defined(ASSIMP_BUILD_ARM_32BIT_ARCHITECTURE)
- << " arm32"
-#else
-# error unknown architecture
-#endif
-
-#if defined(_MSC_VER)
- << " msvc"
-#elif defined(__GNUC__)
- << " gcc"
-#else
-# warning unknown compiler
-#endif
-
-#ifndef NDEBUG
- << " debug"
-#endif
-
- << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
- << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "")
- << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "")
- );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the given file and returns its contents if successful.
-const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- const std::string pFile(_pFile);
-
- // ----------------------------------------------------------------------
- // Put a large try block around everything to catch all std::exception's
- // that might be thrown by STL containers or by new().
- // ImportErrorException's are throw by ourselves and caught elsewhere.
- //-----------------------------------------------------------------------
-
- WriteLogOpening(pFile);
-
-#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- try
-#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- {
- // Check whether this Importer instance has already loaded
- // a scene. In this case we need to delete the old one
- if (pimpl->mScene) {
-
- DefaultLogger::get()->debug("(Deleting previous scene)");
- FreeScene();
- }
-
- // First check if the file is accessable at all
- if ( !pimpl->mIOHandler->Exists( pFile)) {
-
- pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
- DefaultLogger::get()->error(pimpl->mErrorString);
- return NULL;
- }
-
- boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
- if (profiler) {
- profiler->BeginRegion("total");
- }
-
- // Find an worker class which can handle the file
- BaseImporter* imp = NULL;
- for ( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
-
- if ( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
- imp = pimpl->mImporter[a];
- break;
- }
- }
-
- if (!imp) {
- // not so bad yet ... try format auto detection.
- const std::string::size_type s = pFile.find_last_of('.');
- if (s != std::string::npos) {
- DefaultLogger::get()->info("File extension now known, trying signature-based detection");
- for ( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
-
- if ( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
- imp = pimpl->mImporter[a];
- break;
- }
- }
- }
- // Put a proper error message if no suitable importer was found
- if ( !imp) {
- pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
- DefaultLogger::get()->error(pimpl->mErrorString);
- return NULL;
- }
- }
-
- // Dispatch the reading to the worker class for this format
- DefaultLogger::get()->info("Found a matching importer for this file format");
- pimpl->mProgressHandler->Update();
-
- if (profiler) {
- profiler->BeginRegion("import");
- }
-
- pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
- pimpl->mProgressHandler->Update();
-
- if (profiler) {
- profiler->EndRegion("import");
- }
-
- // If successful, apply all active post processing steps to the imported data
- if ( pimpl->mScene) {
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called.
- if (pFlags & aiProcess_ValidateDataStructure)
- {
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if (!pimpl->mScene) {
- return NULL;
- }
- }
-#endif // no validation
-
- // Preprocess the scene and prepare it for post-processing
- if (profiler) {
- profiler->BeginRegion("preprocess");
- }
-
- ScenePreprocessor pre(pimpl->mScene);
- pre.ProcessScene();
-
- pimpl->mProgressHandler->Update();
- if (profiler) {
- profiler->EndRegion("preprocess");
- }
-
- // Ensure that the validation process won't be called twice
- ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));
- }
- // if failed, extract the error string
- else if ( !pimpl->mScene) {
- pimpl->mErrorString = imp->GetErrorText();
- }
-
- // clear any data allocated by post-process steps
- pimpl->mPPShared->Clean();
-
- if (profiler) {
- profiler->EndRegion("total");
- }
- }
-#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- catch (std::exception &e)
- {
-#if (defined _MSC_VER) && (defined _CPPRTTI)
- // if we have RTTI get the full name of the exception that occured
- pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what();
-#else
- pimpl->mErrorString = std::string("std::exception: ") + e.what();
-#endif
-
- DefaultLogger::get()->error(pimpl->mErrorString);
- delete pimpl->mScene; pimpl->mScene = NULL;
- }
-#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
-
- // either successful or failure - the pointer expresses it anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Apply post-processing to the currently bound scene
-const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // Return immediately if no scene is active
- if (!pimpl->mScene) {
- return NULL;
- }
-
- // If no flags are given, return the current scene with no further action
- if (!pFlags) {
- return pimpl->mScene;
- }
-
- // In debug builds: run basic flag validation
- ai_assert(_ValidateFlags(pFlags));
- DefaultLogger::get()->info("Entering post processing pipeline");
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- // The ValidateDS process plays an exceptional role. It isn't contained in the global
- // list of post-processing steps, so we need to call it manually.
- if (pFlags & aiProcess_ValidateDataStructure)
- {
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if (!pimpl->mScene) {
- return NULL;
- }
- }
-#endif // no validation
-#ifdef _DEBUG
- if (pimpl->bExtraVerbose)
- {
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- DefaultLogger::get()->error("Verbose Import is not available due to build settings");
-#endif // no validation
- pFlags |= aiProcess_ValidateDataStructure;
- }
-#else
- if (pimpl->bExtraVerbose) {
- DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting");
- }
-#endif // ! DEBUG
-
- boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
- for ( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
-
- BaseProcess* process = pimpl->mPostProcessingSteps[a];
- if ( process->IsActive( pFlags)) {
-
- if (profiler) {
- profiler->BeginRegion("postprocess");
- }
-
- process->ExecuteOnScene ( this );
- pimpl->mProgressHandler->Update();
-
- if (profiler) {
- profiler->EndRegion("postprocess");
- }
- }
- if ( !pimpl->mScene) {
- break;
- }
-#ifdef _DEBUG
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- continue;
-#endif // no validation
-
- // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
- if (pimpl->bExtraVerbose) {
- DefaultLogger::get()->debug("Verbose Import: revalidating data structures");
-
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if ( !pimpl->mScene) {
- DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures");
- break;
- }
- }
-#endif // ! DEBUG
- }
-
- // clear any data allocated by post-process steps
- pimpl->mPPShared->Clean();
- DefaultLogger::get()->info("Leaving post processing pipeline");
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to check whether an extension is supported by ASSIMP
-bool Importer::IsExtensionSupported(const char* szExtension) const
-{
- return NULL != FindLoader(szExtension);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a loader plugin for a given file extension
-BaseImporter* Importer::FindLoader (const char* szExtension) const
-{
- ai_assert(szExtension);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // skip over wildcard and dot characters at string head --
- for (;*szExtension == '*' || *szExtension == '.'; ++szExtension) {};
-
- std::string ext(szExtension);
- if (ext.empty()) {
- return NULL;
- }
- std::transform(ext.begin(),ext.end(), ext.begin(), tolower);
-
- std::set<std::string> str;
- for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
- str.clear();
-
- (*i)->GetExtensionList(str);
- for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) {
- if (ext == *it) {
- return (*i);
- }
- }
- }
- ASSIMP_END_EXCEPTION_REGION(BaseImporter*);
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to build a list of all file extensions supported by ASSIMP
-void Importer::GetExtensionList(aiString& szOut) const
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::set<std::string> str;
- for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
- (*i)->GetExtensionList(str);
- }
-
- for (std::set<std::string>::const_iterator it = str.begin();; ) {
- szOut.Append("*.");
- szOut.Append((*it).c_str());
-
- if (++it == str.end()) {
- break;
- }
- szOut.Append(";");
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-void Importer::SetPropertyInteger(const char* szName, int iValue,
- bool* bWasExisting /*= NULL*/)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue,bWasExisting);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-void Importer::SetPropertyFloat(const char* szName, float iValue,
- bool* bWasExisting /*= NULL*/)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- SetGenericProperty<float>(pimpl->mFloatProperties, szName,iValue,bWasExisting);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-void Importer::SetPropertyString(const char* szName, const std::string& value,
- bool* bWasExisting /*= NULL*/)
-{
- try {
- std::cout << "";
- }
- catch (...) {
- try {
- throw;
- }
- catch(std::exception&) {
- return;
- }
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value,bWasExisting);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-int Importer::GetPropertyInteger(const char* szName,
- int iErrorReturn /*= 0xffffffff*/) const
-{
- return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-float Importer::GetPropertyFloat(const char* szName,
- float iErrorReturn /*= 10e10*/) const
-{
- return GetGenericProperty<float>(pimpl->mFloatProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-const std::string& Importer::GetPropertyString(const char* szName,
- const std::string& iErrorReturn /*= ""*/) const
-{
- return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the memory requirements of a single node
-inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
-{
- iScene += sizeof(aiNode);
- iScene += sizeof(unsigned int) * pcNode->mNumMeshes;
- iScene += sizeof(void*) * pcNode->mNumChildren;
-
- for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
- AddNodeWeight(iScene,pcNode->mChildren[i]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the memory requirements of the scene
-void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
-{
- in = aiMemoryInfo();
- aiScene* mScene = pimpl->mScene;
-
- // return if we have no scene loaded
- if (!pimpl->mScene)
- return;
-
-
- in.total = sizeof(aiScene);
-
- // add all meshes
- for (unsigned int i = 0; i < mScene->mNumMeshes;++i)
- {
- in.meshes += sizeof(aiMesh);
- if (mScene->mMeshes[i]->HasPositions()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
-
- if (mScene->mMeshes[i]->HasNormals()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
-
- if (mScene->mMeshes[i]->HasTangentsAndBitangents()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2;
- }
-
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) {
- if (mScene->mMeshes[i]->HasVertexColors(a)) {
- in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices;
- }
- else break;
- }
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
- if (mScene->mMeshes[i]->HasTextureCoords(a)) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
- else break;
- }
- if (mScene->mMeshes[i]->HasBones()) {
- in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones;
- for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) {
- in.meshes += sizeof(aiBone);
- in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight);
- }
- }
- in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces;
- }
- in.total += in.meshes;
-
- // add all embedded textures
- for (unsigned int i = 0; i < mScene->mNumTextures;++i) {
- const aiTexture* pc = mScene->mTextures[i];
- in.textures += sizeof(aiTexture);
- if (pc->mHeight) {
- in.textures += 4 * pc->mHeight * pc->mWidth;
- }
- else in.textures += pc->mWidth;
- }
- in.total += in.textures;
-
- // add all animations
- for (unsigned int i = 0; i < mScene->mNumAnimations;++i) {
- const aiAnimation* pc = mScene->mAnimations[i];
- in.animations += sizeof(aiAnimation);
-
- // add all bone anims
- for (unsigned int a = 0; a < pc->mNumChannels; ++a) {
- const aiNodeAnim* pc2 = pc->mChannels[i];
- in.animations += sizeof(aiNodeAnim);
- in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey);
- in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey);
- in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey);
- }
- }
- in.total += in.animations;
-
- // add all cameras and all lights
- in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras;
- in.total += in.lights = sizeof(aiLight) * mScene->mNumLights;
-
- // add all nodes
- AddNodeWeight(in.nodes,mScene->mRootNode);
- in.total += in.nodes;
-
- // add all materials
- for (unsigned int i = 0; i < mScene->mNumMaterials;++i) {
- const aiMaterial* pc = mScene->mMaterials[i];
- in.materials += sizeof(aiMaterial);
- in.materials += pc->mNumAllocated * sizeof(void*);
-
- for (unsigned int a = 0; a < pc->mNumProperties;++a) {
- in.materials += pc->mProperties[a]->mDataLength;
- }
- }
- in.total += in.materials;
-}
-
diff --git a/3rdparty/assimp/code/ImproveCacheLocality.cpp b/3rdparty/assimp/code/ImproveCacheLocality.cpp
deleted file mode 100644
index a25d8878..00000000
--- a/3rdparty/assimp/code/ImproveCacheLocality.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to improve the cache locality of a mesh.
- * <br>
- * The algorithm is roughly basing on this paper:
- * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf
- * .. although overdraw rduction isn't implemented yet ...
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "ImproveCacheLocality.h"
-#include "VertexTriangleAdjacency.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() {
- configCacheDepth = PP_ICL_PTCACHE_SIZE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_ImproveCacheLocality) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration
-void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
- configCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
-{
- if (!pScene->mNumMeshes) {
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess skipped; there are no meshes");
- return;
- }
-
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess begin");
-
- float out = 0.f;
- unsigned int numf = 0, numm = 0;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++){
- const float res = ProcessMesh( pScene->mMeshes[a],a);
- if (res) {
- numf += pScene->mMeshes[a]->mNumFaces;
- out += res;
- ++numm;
- }
- }
- if (!DefaultLogger::isNullLogger()) {
- char szBuff[128]; // should be sufficiently large in every case
- ::sprintf(szBuff,"Cache relevant are %i meshes (%i faces). Average output ACMR is %f",
- numm,numf,out/numf);
-
- DefaultLogger::get()->info(szBuff);
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess finished. ");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Improves the cache coherency of a specific mesh
-float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum)
-{
- // TODO: rewrite this to use std::vector or boost::shared_array
- ai_assert(NULL != pMesh);
-
- // Check whether the input data is valid
- // - there must be vertices and faces
- // - all faces must be triangulated or we can't operate on them
- if (!pMesh->HasFaces() || !pMesh->HasPositions())
- return 0.f;
-
- if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
- DefaultLogger::get()->error("This algorithm works on triangle meshes only");
- return 0.f;
- }
-
- float fACMR = 3.f;
- const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
-
- // Input ACMR is for logging purposes only
- if (!DefaultLogger::isNullLogger()) {
-
- unsigned int* piFIFOStack = new unsigned int[configCacheDepth];
- memset(piFIFOStack,0xff,configCacheDepth*sizeof(unsigned int));
- unsigned int* piCur = piFIFOStack;
- const unsigned int* const piCurEnd = piFIFOStack + configCacheDepth;
-
- // count the number of cache misses
- unsigned int iCacheMisses = 0;
- for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) {
-
- for (unsigned int qq = 0; qq < 3;++qq) {
- bool bInCache = false;
-
- for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) {
- if (*pp == pcFace->mIndices[qq]) {
- // the vertex is in cache
- bInCache = true;
- break;
- }
- }
- if (!bInCache) {
- ++iCacheMisses;
- if (piCurEnd == piCur) {
- piCur = piFIFOStack;
- }
- *piCur++ = pcFace->mIndices[qq];
- }
- }
- }
- delete[] piFIFOStack;
- fACMR = (float)iCacheMisses / pMesh->mNumFaces;
- if (3.0 == fACMR) {
- char szBuff[128]; // should be sufficiently large in every case
-
- // the JoinIdenticalVertices process has not been executed on this
- // mesh, otherwise this value would normally be at least minimally
- // smaller than 3.0 ...
- sprintf(szBuff,"Mesh %i: Not suitable for vcache optimization",meshNum);
- DefaultLogger::get()->warn(szBuff);
- return 0.f;
- }
- }
-
- // first we need to build a vertex-triangle adjacency list
- VertexTriangleAdjacency adj(pMesh->mFaces,pMesh->mNumFaces, pMesh->mNumVertices,true);
-
- // build a list to store per-vertex caching time stamps
- unsigned int* const piCachingStamps = new unsigned int[pMesh->mNumVertices];
- memset(piCachingStamps,0x0,pMesh->mNumVertices*sizeof(unsigned int));
-
- // allocate an empty output index buffer. We store the output indices in one large array.
- // Since the number of triangles won't change the input faces can be reused. This is how
- // we save thousands of redundant mini allocations for aiFace::mIndices
- const unsigned int iIdxCnt = pMesh->mNumFaces*3;
- unsigned int* const piIBOutput = new unsigned int[iIdxCnt];
- unsigned int* piCSIter = piIBOutput;
-
- // allocate the flag array to hold the information
- // whether a face has already been emitted or not
- std::vector<bool> abEmitted(pMesh->mNumFaces,false);
-
- // dead-end vertex index stack
- std::stack<unsigned int> sDeadEndVStack;
-
- // create a copy of the piNumTriPtr buffer
- unsigned int* const piNumTriPtr = adj.mLiveTriangles;
- const unsigned int* const piNumTriPtrNoModify = new unsigned int[pMesh->mNumVertices];
- memcpy(const_cast<unsigned int* const> (piNumTriPtrNoModify),piNumTriPtr,
- pMesh->mNumVertices * sizeof(unsigned int));
-
- // get the largest number of referenced triangles and allocate the "candidate buffer"
- unsigned int iMaxRefTris = 0; {
- const unsigned int* piCur = adj.mLiveTriangles;
- const unsigned int* const piCurEnd = adj.mLiveTriangles+pMesh->mNumVertices;
- for (;piCur != piCurEnd;++piCur) {
- iMaxRefTris = std::max(iMaxRefTris,*piCur);
- }
- }
- unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
- unsigned int iCacheMisses = 0;
-
- // ...................................................................................
- /** PSEUDOCODE for the algorithm
-
- A = Build-Adjacency(I) Vertex-triangle adjacency
- L = Get-Triangle-Counts(A) Per-vertex live triangle counts
- C = Zero(Vertex-Count(I)) Per-vertex caching time stamps
- D = Empty-Stack() Dead-end vertex stack
- E = False(Triangle-Count(I)) Per triangle emitted flag
- O = Empty-Index-Buffer() Empty output buffer
- f = 0 Arbitrary starting vertex
- s = k+1, i = 1 Time stamp and cursor
- while f >= 0 For all valid fanning vertices
- N = Empty-Set() 1-ring of next candidates
- for each Triangle t in Neighbors(A, f)
- if !Emitted(E,t)
- for each Vertex v in t
- Append(O,v) Output vertex
- Push(D,v) Add to dead-end stack
- Insert(N,v) Register as candidate
- L[v] = L[v]-1 Decrease live triangle count
- if s-C[v] > k If not in cache
- C[v] = s Set time stamp
- s = s+1 Increment time stamp
- E[t] = true Flag triangle as emitted
- Select next fanning vertex
- f = Get-Next-Vertex(I,i,k,N,C,s,L,D)
- return O
- */
- // ...................................................................................
-
- int ivdx = 0;
- int ics = 1;
- int iStampCnt = configCacheDepth+1;
- while (ivdx >= 0) {
-
- unsigned int icnt = piNumTriPtrNoModify[ivdx];
- unsigned int* piList = adj.GetAdjacentTriangles(ivdx);
- unsigned int* piCurCandidate = piCandidates;
-
- // get all triangles in the neighborhood
- for (unsigned int tri = 0; tri < icnt;++tri) {
-
- // if they have not yet been emitted, add them to the output IB
- const unsigned int fidx = *piList++;
- if (!abEmitted[fidx]) {
-
- // so iterate through all vertices of the current triangle
- const aiFace* pcFace = &pMesh->mFaces[ fidx ];
- for (unsigned int* p = pcFace->mIndices, *p2 = pcFace->mIndices+3;p != p2;++p) {
- const unsigned int dp = *p;
-
- // the current vertex won't have any free triangles after this step
- if (ivdx != (int)dp) {
- // append the vertex to the dead-end stack
- sDeadEndVStack.push(dp);
-
- // register as candidate for the next step
- *piCurCandidate++ = dp;
-
- // decrease the per-vertex triangle counts
- piNumTriPtr[dp]--;
- }
-
- // append the vertex to the output index buffer
- *piCSIter++ = dp;
-
- // if the vertex is not yet in cache, set its cache count
- if (iStampCnt-piCachingStamps[dp] > configCacheDepth) {
- piCachingStamps[dp] = iStampCnt++;
- ++iCacheMisses;
- }
- }
- // flag triangle as emitted
- abEmitted[fidx] = true;
- }
- }
-
- // the vertex has now no living adjacent triangles anymore
- piNumTriPtr[ivdx] = 0;
-
- // get next fanning vertex
- ivdx = -1;
- int max_priority = -1;
- for (unsigned int* piCur = piCandidates;piCur != piCurCandidate;++piCur) {
- register const unsigned int dp = *piCur;
-
- // must have live triangles
- if (piNumTriPtr[dp] > 0) {
- int priority = 0;
-
- // will the vertex be in cache, even after fanning occurs?
- unsigned int tmp;
- if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= configCacheDepth) {
- priority = tmp;
- }
-
- // keep best candidate
- if (priority > max_priority) {
- max_priority = priority;
- ivdx = dp;
- }
- }
- }
- // did we reach a dead end?
- if (-1 == ivdx) {
- // need to get a non-local vertex for which we have a good chance that it is still
- // in the cache ...
- while (!sDeadEndVStack.empty()) {
- unsigned int iCachedIdx = sDeadEndVStack.top();
- sDeadEndVStack.pop();
- if (piNumTriPtr[ iCachedIdx ] > 0) {
- ivdx = iCachedIdx;
- break;
- }
- }
-
- if (-1 == ivdx) {
- // well, there isn't such a vertex. Simply get the next vertex in input order and
- // hope it is not too bad ...
- while (ics < (int)pMesh->mNumVertices) {
- ++ics;
- if (piNumTriPtr[ics] > 0) {
- ivdx = ics;
- break;
- }
- }
- }
- }
- }
- float fACMR2 = 0.0f;
- if (!DefaultLogger::isNullLogger()) {
- fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
-
- // very intense verbose logging ... prepare for much text if there are many meshes
- if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
- char szBuff[128]; // should be sufficiently large in every case
-
- ::sprintf(szBuff,"Mesh %i | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
- ((fACMR - fACMR2) / fACMR) * 100.f);
- DefaultLogger::get()->debug(szBuff);
- }
-
- fACMR2 *= pMesh->mNumFaces;
- }
- // sort the output index buffer back to the input array
- piCSIter = piIBOutput;
- for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) {
- pcFace->mIndices[0] = *piCSIter++;
- pcFace->mIndices[1] = *piCSIter++;
- pcFace->mIndices[2] = *piCSIter++;
- }
-
- // delete temporary storage
- delete[] piCachingStamps;
- delete[] piIBOutput;
- delete[] piCandidates;
- delete[] piNumTriPtrNoModify;
- return fACMR2;
-}
diff --git a/3rdparty/assimp/code/ImproveCacheLocality.h b/3rdparty/assimp/code/ImproveCacheLocality.h
deleted file mode 100644
index 58613e04..00000000
--- a/3rdparty/assimp/code/ImproveCacheLocality.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to reorder faces for
- better cache locality*/
-#ifndef AI_IMPROVECACHELOCALITY_H_INC
-#define AI_IMPROVECACHELOCALITY_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiTypes.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
- * cache locality. It tries to arrange all faces to fans and to render
- * faces which share vertices directly one after the other.
- *
- * @note This step expects triagulated input data.
- */
-class ASSIMP_API ImproveCacheLocalityProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- ImproveCacheLocalityProcess();
-
- /** Destructor, private as well */
- ~ImproveCacheLocalityProcess();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether the pp step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Executes the pp step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Configures the pp step
- void SetupProperties(const Importer* pImp);
-
-protected:
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given mesh
- * @param pMesh The mesh to process.
- * @param meshNum Index of the mesh to process
- */
- float ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
-
-private:
- //! Configuration parameter: specifies the size of the cache to
- //! optimize the vertex data for.
- unsigned int configCacheDepth;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IMPROVECACHELOCALITY_H_INC
diff --git a/3rdparty/assimp/code/JoinVerticesProcess.cpp b/3rdparty/assimp/code/JoinVerticesProcess.cpp
deleted file mode 100644
index 88f5db12..00000000
--- a/3rdparty/assimp/code/JoinVerticesProcess.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the post processing step to join identical vertices
- * for all imported meshes
- */
-
-#include <QtCore/qdebug.h>
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-
-#include "JoinVerticesProcess.h"
-#include "ProcessHelper.h"
-#include "Vertex.h"
-#include "TinyFormatter.h"
-
-using namespace Assimp;
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-JoinVerticesProcess::JoinVerticesProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-JoinVerticesProcess::~JoinVerticesProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void JoinVerticesProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("JoinVerticesProcess begin");
-
- // get the total number of vertices BEFORE the step is executed
- int iNumOldVertices = 0;
- if (!DefaultLogger::isNullLogger()) {
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- iNumOldVertices += pScene->mMeshes[a]->mNumVertices;
- }
- }
- // execute the step
- int iNumVertices = 0;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
-
- // if logging is active, print detailed statistics
- if (!DefaultLogger::isNullLogger())
- {
- if (iNumOldVertices == iNumVertices)
- {
- DefaultLogger::get()->debug("JoinVerticesProcess finished ");
- } else
- {
- char szBuff[128]; // should be sufficiently large in every case
- sprintf(szBuff,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
- iNumOldVertices,
- iNumVertices,
- ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f);
- DefaultLogger::get()->info(szBuff);
- }
- }
-
- pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unites identical vertices in the given mesh
-int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
-{
- BOOST_STATIC_ASSERT( AI_MAX_NUMBER_OF_COLOR_SETS == 4);
- BOOST_STATIC_ASSERT( AI_MAX_NUMBER_OF_TEXTURECOORDS == 4);
-
- // Return early if we don't have any positions
- if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
- return 0;
- }
-
- // We'll never have more vertices afterwards.
- std::vector<Vertex> uniqueVertices;
-
-#ifndef __GCCE__
-#ifndef __arm__
- try {
- uniqueVertices.reserve( pMesh->mNumVertices);
- } catch (...) {
- qWarning("Unable to reserve vertex space");
- return 0;
- }
-#endif
-#endif
-
- // For each vertex the index of the vertex it was replaced by.
- // Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
- // whether a new vertex was created for the index (true) or if it was replaced by an existing
- // unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
- // branching performance.
- BOOST_STATIC_ASSERT(AI_MAX_VERTICES == 0x7fffffff);
- std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
-
- // A little helper to find locally close vertices faster.
- // Try to reuse the lookup table from the last step.
- const static float epsilon = 1e-5f;
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
-
- typedef std::pair<SpatialSort,float> SpatPair;
- if (shared) {
- std::vector<SpatPair >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf) {
- SpatPair& blubb = (*avf)[meshIndex];
- vertexFinder = &blubb.first;
- }
- }
- if (!vertexFinder) {
- // bad, need to compute it.
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- }
-
- // Squared because we check against squared length of the vector difference
- static const float squareEpsilon = epsilon * epsilon;
-
- // Again, better waste some bytes than a realloc ...
- std::vector<unsigned int> verticesFound;
- verticesFound.reserve(10);
-
- // Run an optimized code path if we don't have multiple UVs or vertex colors.
- // This should yield false in more than 99% of all imports ...
- const bool complex = (
- pMesh->mTextureCoords[1] ||
- pMesh->mTextureCoords[2] ||
- pMesh->mTextureCoords[3] ||
- pMesh->mColors[0] ||
- pMesh->mColors[1] ||
- pMesh->mColors[2] ||
- pMesh->mColors[3] );
-
- // Now check each vertex if it brings something new to the table
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- // collect the vertex data
- Vertex v(pMesh,a);
-
- // collect all vertices that are close enough to the given position
- vertexFinder->FindIdenticalPositions( v.position, verticesFound);
- unsigned int matchIndex = 0xffffffff;
-
- // check all unique vertices close to the position if this vertex is already present among them
- for ( unsigned int b = 0; b < verticesFound.size(); b++) {
- const unsigned int vidx = verticesFound[b];
- const unsigned int uidx = replaceIndex[ vidx];
- if ( uidx & 0x80000000)
- continue;
-
- const Vertex& uv = uniqueVertices[ uidx];
- // Position mismatch is impossible - the vertex finder already discarded all non-matching positions
-
- // We just test the other attributes even if they're not present in the mesh.
- // In this case they're initialized to 0 so the comparision succeeds.
- // By this method the non-present attributes are effectively ignored in the comparision.
- if ( (uv.normal - v.normal).SquareLength() > squareEpsilon)
- continue;
- if ( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
- continue;
- if ( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
- continue;
- if ( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
- continue;
-
- // Usually we won't have vertex colors or multiple UVs, so we can skip from here
- // Actually this increases runtime performance slightly, at least if branch
- // prediction is on our side.
- if (complex){
- // manually unrolled because continue wouldn't work as desired in an inner loop
- if ( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
- continue;
- if ( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
- continue;
- if ( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
- continue;
- if ( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
- continue;
-
- // texture coord matching manually unrolled as well
- if ( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
- continue;
- if ( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
- continue;
- if ( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
- continue;
- }
-
- // we're still here -> this vertex perfectly matches our given vertex
- matchIndex = uidx;
- break;
- }
-
- // found a replacement vertex among the uniques?
- if ( matchIndex != 0xffffffff)
- {
- // store where to found the matching unique vertex
- replaceIndex[a] = matchIndex | 0x80000000;
- }
- else
- {
- // no unique vertex matches it upto now -> so add it
- replaceIndex[a] = (unsigned int)uniqueVertices.size();
- uniqueVertices.push_back( v);
- }
- }
-
- if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
- DefaultLogger::get()->debug((Formatter::format(),
- "Mesh ",meshIndex,
- " (",
- (pMesh->mName.length ? pMesh->mName.data : "unnamed"),
- ") | Verts in: ",pMesh->mNumVertices,
- " out: ",
- uniqueVertices.size(),
- " | ~",
- ((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
- "%"
- ));
- }
-
- // replace vertex data with the unique data sets
- pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
-
- // ----------------------------------------------------------------------------
- // NOTE - we're *not* calling Vertex::SortBack() because it would check for
- // presence of every single vertex component once PER VERTEX. And our CPU
- // dislikes branches, even if they're easily predictable.
- // ----------------------------------------------------------------------------
-
- // Position
- delete [] pMesh->mVertices;
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- pMesh->mVertices[a] = uniqueVertices[a].position;
-
- // Normals, if present
- if ( pMesh->mNormals)
- {
- delete [] pMesh->mNormals;
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mNormals[a] = uniqueVertices[a].normal;
- }
- }
- // Tangents, if present
- if ( pMesh->mTangents)
- {
- delete [] pMesh->mTangents;
- pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mTangents[a] = uniqueVertices[a].tangent;
- }
- }
- // Bitangents as well
- if ( pMesh->mBitangents)
- {
- delete [] pMesh->mBitangents;
- pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
- for ( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mBitangents[a] = uniqueVertices[a].bitangent;
- }
- }
- // Vertex colors
- for ( unsigned int a = 0; pMesh->HasVertexColors(a); a++)
- {
- delete [] pMesh->mColors[a];
- pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
- for ( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
- pMesh->mColors[a][b] = uniqueVertices[b].colors[a];
- }
- }
- // Texture coords
- for ( unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
- {
- delete [] pMesh->mTextureCoords[a];
- pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
- for ( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
- pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
- }
- }
-
- // adjust the indices in all faces
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- aiFace& face = pMesh->mFaces[a];
- for ( unsigned int b = 0; b < face.mNumIndices; b++) {
- face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000;
- }
- }
-
- // adjust bone vertex weights.
- for ( int a = 0; a < (int)pMesh->mNumBones; a++)
- {
- aiBone* bone = pMesh->mBones[a];
- std::vector<aiVertexWeight> newWeights;
- newWeights.reserve( bone->mNumWeights);
-
- for ( unsigned int b = 0; b < bone->mNumWeights; b++)
- {
- const aiVertexWeight& ow = bone->mWeights[b];
- // if the vertex is a unique one, translate it
- if ( !(replaceIndex[ow.mVertexId] & 0x80000000))
- {
- aiVertexWeight nw;
- nw.mVertexId = replaceIndex[ow.mVertexId];
- nw.mWeight = ow.mWeight;
- newWeights.push_back( nw);
- }
- }
-
- if (newWeights.size() > 0) {
- // kill the old and replace them with the translated weights
- delete [] bone->mWeights;
- bone->mNumWeights = (unsigned int)newWeights.size();
-
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
- }
- else {
-
- /* NOTE:
- *
- * In the algorithm above we're assuming that there are no vertices
- * with a different bone weight setup at the same position. That wouldn't
- * make sense, but it is not absolutely impossible. SkeletonMeshBuilder
- * for example generates such input data if two skeleton points
- * share the same position. Again this doesn't make sense but is
- * reality for some model formats (MD5 for example uses these special
- * nodes as attachment tags for its weapons).
- *
- * Then it is possible that a bone has no weights anymore .... as a quick
- * workaround, we're just removing these bones. If they're animated,
- * model geometry might be modified but at least there's no risk of a crash.
- */
- delete bone;
- --pMesh->mNumBones;
- for (unsigned int n = a; n < pMesh->mNumBones; ++n) {
- pMesh->mBones[n] = pMesh->mBones[n+1];
- }
-
- --a;
- DefaultLogger::get()->warn("Removing bone -> no weights remaining");
- }
- }
- return pMesh->mNumVertices;
-}
-
-#endif // !! ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
diff --git a/3rdparty/assimp/code/JoinVerticesProcess.h b/3rdparty/assimp/code/JoinVerticesProcess.h
deleted file mode 100644
index 0ce00ab5..00000000
--- a/3rdparty/assimp/code/JoinVerticesProcess.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to join identical vertices
- on all imported meshes.*/
-#ifndef AI_JOINVERTICESPROCESS_H_INC
-#define AI_JOINVERTICESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiTypes.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-class JoinVerticesTest;
-
-// ---------------------------------------------------------------------------
-/** The JoinVerticesProcess unites identical vertices in all imported meshes.
- * By default the importer returns meshes where each face addressed its own
- * set of vertices even if that means that identical vertices are stored multiple
- * times. The JoinVerticesProcess finds these identical vertices and
- * erases all but one of the copies. This usually reduces the number of vertices
- * in a mesh by a serious amount and is the standard form to render a mesh.
- */
-class ASSIMP_API JoinVerticesProcess : public BaseProcess
-{
- friend class Importer;
- friend class JoinVerticesTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- JoinVerticesProcess();
-
- /** Destructor, private as well */
- ~JoinVerticesProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
- // -------------------------------------------------------------------
- /** Unites identical vertices in the given mesh.
- * @param pMesh The mesh to process.
- * @param meshIndex Index of the mesh to process
- */
- int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
-private:
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/3rdparty/assimp/code/LWOAnimation.cpp b/3rdparty/assimp/code/LWOAnimation.cpp
deleted file mode 100644
index 7b06b267..00000000
--- a/3rdparty/assimp/code/LWOAnimation.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file LWOAnimation.cpp
- * @brief LWOAnimationResolver utility class
- *
- * It's a very generic implementation of LightWave's system of
- * componentwise-animated stuff. The one and only fully free
- * implementation of LightWave envelopes of which I know.
-*/
-
-#include "AssimpPCH.h"
-#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
-
-// internal headers
-#include "LWOFileData.h"
-
-using namespace Assimp;
-using namespace Assimp::LWO;
-
-// ------------------------------------------------------------------------------------------------
-// Construct an animation resolver from a given list of envelopes
-AnimResolver::AnimResolver(std::list<Envelope>& _envelopes,double tick)
- : envelopes (_envelopes)
- , sample_rate (0.)
-{
- trans_x = trans_y = trans_z = NULL;
- rotat_x = rotat_y = rotat_z = NULL;
- scale_x = scale_y = scale_z = NULL;
-
- first = last = 150392.;
-
- // find transformation envelopes
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).old_first = 0;
- (*it).old_last = (*it).keys.size()-1;
-
- if ((*it).keys.empty()) continue;
- switch ((*it).type) {
-
- // translation
- case LWO::EnvelopeType_Position_X:
- trans_x = &*it;break;
- case LWO::EnvelopeType_Position_Y:
- trans_y = &*it;break;
- case LWO::EnvelopeType_Position_Z:
- trans_z = &*it;break;
-
- // rotation
- case LWO::EnvelopeType_Rotation_Heading:
- rotat_x = &*it;break;
- case LWO::EnvelopeType_Rotation_Pitch:
- rotat_y = &*it;break;
- case LWO::EnvelopeType_Rotation_Bank:
- rotat_z = &*it;break;
-
- // scaling
- case LWO::EnvelopeType_Scaling_X:
- scale_x = &*it;break;
- case LWO::EnvelopeType_Scaling_Y:
- scale_y = &*it;break;
- case LWO::EnvelopeType_Scaling_Z:
- scale_z = &*it;break;
- default:
- continue;
- };
-
- // convert from seconds to ticks
- for (std::vector<LWO::Key>::iterator d = (*it).keys.begin(); d != (*it).keys.end(); ++d)
- (*d).time *= tick;
-
- // set default animation range (minimum and maximum time value for which we have a keyframe)
- first = std::min(first, (*it).keys.front().time );
- last = std::max(last, (*it).keys.back().time );
- }
-
- // deferred setup of animation range to increase performance.
- // typically the application will want to specify its own.
- need_to_setup = true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reset all envelopes to their original contents
-void AnimResolver::ClearAnimRangeSetup()
-{
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).keys.erase((*it).keys.begin(),(*it).keys.begin()+(*it).old_first);
- (*it).keys.erase((*it).keys.begin()+(*it).old_last+1,(*it).keys.end());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Insert additional keys to match LWO's pre& post behaviours.
-void AnimResolver::UpdateAnimRangeSetup()
-{
- // XXX doesn't work yet (hangs if more than one envelope channels needs to be interpolated)
-
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
- if ((*it).keys.empty()) continue;
-
- const double my_first = (*it).keys.front().time;
- const double my_last = (*it).keys.back().time;
-
- const double delta = my_last-my_first;
- const size_t old_size = (*it).keys.size();
-
- const float value_delta = (*it).keys.back().value - (*it).keys.front().value;
-
- // NOTE: We won't handle reset, linear and constant here.
- // See DoInterpolation() for their implementation.
-
- // process pre behaviour
- switch ((*it).pre) {
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate:
- {
- const double start_time = delta - fmod(my_first-first,delta);
- std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
- std::bind1st(std::greater<double>(),start_time)),m;
-
- size_t ofs = 0;
- if (n != (*it).keys.end()) {
- // copy from here - don't use iterators, insert() would invalidate them
- ofs = (*it).keys.end()-n;
- (*it).keys.insert((*it).keys.begin(),ofs,LWO::Key());
-
- std::copy((*it).keys.end()-ofs,(*it).keys.end(),(*it).keys.begin());
- }
-
- // do full copies. again, no iterators
- const unsigned int num = (unsigned int)((my_first-first) / delta);
- (*it).keys.resize((*it).keys.size() + num*old_size);
-
- n = (*it).keys.begin()+ofs;
- bool reverse = false;
- for (unsigned int i = 0; i < num; ++i) {
- m = n+old_size*(i+1);
- std::copy(n,n+old_size,m);
-
- if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse))
- std::reverse(m,m+old_size-1);
- }
-
- // update time values
- n = (*it).keys.end() - (old_size+1);
- double cur_minus = delta;
- unsigned int tt = 1;
- for (const double tmp = delta*(num+1);cur_minus <= tmp;cur_minus += delta,++tt) {
- m = (delta == tmp ? (*it).keys.begin() : n - (old_size+1));
- for (;m != n; --n) {
- (*n).time -= cur_minus;
-
- // offset repeat? add delta offset to key value
- if ((*it).pre == LWO::PrePostBehaviour_OffsetRepeat) {
- (*n).value += tt * value_delta;
- }
- }
- }
- break;
- }
- default:
- // silence compiler warning
- break;
- }
-
- // process post behaviour
- switch ((*it).post) {
-
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate:
-
- break;
-
- default:
- // silence compiler warning
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract bind pose matrix
-void AnimResolver::ExtractBindPose(aiMatrix4x4& out)
-{
- // If we have no envelopes, return identity
- if (envelopes.empty()) {
- out = aiMatrix4x4();
- return;
- }
- aiVector3D angles, scaling(1.f,1.f,1.f), translation;
-
- if (trans_x) translation.x = trans_x->keys[0].value;
- if (trans_y) translation.y = trans_y->keys[0].value;
- if (trans_z) translation.z = trans_z->keys[0].value;
-
- if (rotat_x) angles.x = rotat_x->keys[0].value;
- if (rotat_y) angles.y = rotat_y->keys[0].value;
- if (rotat_z) angles.z = rotat_z->keys[0].value;
-
- if (scale_x) scaling.x = scale_x->keys[0].value;
- if (scale_y) scaling.y = scale_y->keys[0].value;
- if (scale_z) scaling.z = scale_z->keys[0].value;
-
- // build the final matrix
- aiMatrix4x4 s,r,t;
-
- r.FromEulerAnglesXYZ(angles);
- //aiMatrix4x4::RotationY(angles.y,r);
- // fixme: make FromEulerAngles static, too
- aiMatrix4x4::Translation(translation,t);
- aiMatrix4x4::Scaling(scaling,s);
- out = s*r*t;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Do a single interpolation on a channel
-void AnimResolver::DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope* envl,double time, float& fill)
-{
- if (envl->keys.size() == 1) {
- fill = envl->keys[0].value;
- return;
- }
-
- // check whether we're at the beginning of the animation track
- if (cur == envl->keys.begin()) {
-
- // ok ... this depends on pre behaviour now
- // we don't need to handle repeat&offset repeat&oszillate here, see UpdateAnimRangeSetup()
- switch (envl->pre)
- {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur,cur+1,time,fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default : //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
- // check whether we're at the end of the animation track
- else if (cur == envl->keys.end()-1 && time > envl->keys.rbegin()->time) {
- // ok ... this depends on post behaviour now
- switch (envl->post)
- {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur,cur-1,time,fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default : //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
-
- // Otherwise do a simple interpolation
- DoInterpolation2(cur-1,cur,time,fill);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Almost the same, except we won't handle pre/post conditions here
-void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end,double time, float& fill)
-{
- switch ((*end).inter) {
-
- case LWO::IT_STEP:
- // no interpolation at all - take the value of the last key
- fill = (*beg).value;
- return;
- default:
-
- // silence compiler warning
- break;
- }
- // linear interpolation - default
- fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / ((*end).time - (*beg).time)));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Subsample animation track by given key values
-void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& /*out*/,
- double /*time*/ ,double /*sample_delta*/ )
-{
- //ai_assert(out.empty() && sample_delta);
-
- //const double time_start = out.back().mTime;
-// for ()
-}
-
-// ------------------------------------------------------------------------------------------------
-// Track interpolation
-void AnimResolver::InterpolateTrack(std::vector<aiVectorKey>& out,aiVectorKey& fill,double time)
-{
- // subsample animation track?
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- SubsampleAnimTrack(out,time, sample_delta);
- }
-
- fill.mTime = time;
-
- // get x
- if ((*cur_x).time == time) {
- fill.mValue.x = (*cur_x).value;
-
- if (cur_x != envl_x->keys.end()-1) /* increment x */
- ++cur_x;
- else end_x = true;
- }
- else DoInterpolation(cur_x,envl_x,time,(float&)fill.mValue.x);
-
- // get y
- if ((*cur_y).time == time) {
- fill.mValue.y = (*cur_y).value;
-
- if (cur_y != envl_y->keys.end()-1) /* increment y */
- ++cur_y;
- else end_y = true;
- }
- else DoInterpolation(cur_y,envl_y,time,(float&)fill.mValue.y);
-
- // get z
- if ((*cur_z).time == time) {
- fill.mValue.z = (*cur_z).value;
-
- if (cur_z != envl_z->keys.end()-1) /* increment z */
- ++cur_z;
- else end_x = true;
- }
- else DoInterpolation(cur_z,envl_z,time,(float&)fill.mValue.z);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build linearly subsampled keys from three single envelopes, one for each component (x,y,z)
-void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
- LWO::Envelope* _envl_x,
- LWO::Envelope* _envl_y,
- LWO::Envelope* _envl_z,
- unsigned int _flags)
-{
- envl_x = _envl_x;
- envl_y = _envl_y;
- envl_z = _envl_z;
- flags = _flags;
-
- // generate default channels if none are given
- LWO::Envelope def_x, def_y, def_z;
- LWO::Key key_dummy;
- key_dummy.time = 0.f;
- if ((envl_x && envl_x->type == LWO::EnvelopeType_Scaling_X) ||
- (envl_y && envl_y->type == LWO::EnvelopeType_Scaling_Y) ||
- (envl_z && envl_z->type == LWO::EnvelopeType_Scaling_Z)) {
- key_dummy.value = 1.f;
- }
- else key_dummy.value = 0.f;
-
- if (!envl_x) {
- envl_x = &def_x;
- envl_x->keys.push_back(key_dummy);
- }
- if (!envl_y) {
- envl_y = &def_y;
- envl_y->keys.push_back(key_dummy);
- }
- if (!envl_z) {
- envl_z = &def_z;
- envl_z->keys.push_back(key_dummy);
- }
-
- // guess how many keys we'll get
- size_t reserve;
- double sr = 1.;
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- if (!sample_rate)
- sr = 100.f;
- else sr = sample_rate;
- sample_delta = 1.f / sr;
-
- reserve = (size_t)(
- std::max( envl_x->keys.end()->time,
- std::max( envl_y->keys.end()->time, envl_z->keys.end()->time )) * sr);
- }
- else reserve = std::max(envl_x->keys.size(),std::max(envl_x->keys.size(),envl_z->keys.size()));
- out.reserve(reserve+(reserve>>1));
-
- // Iterate through all three arrays at once - it's tricky, but
- // rather interesting to implement.
- cur_x = envl_x->keys.begin();
- cur_y = envl_y->keys.begin();
- cur_z = envl_z->keys.begin();
-
- end_x = end_y = end_z = false;
- while (1) {
-
- aiVectorKey fill;
-
- if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {
-
- // we have a keyframe for all of them defined .. great,
- // we don't need to fucking interpolate here ...
- fill.mTime = (*cur_x).time;
-
- fill.mValue.x = (*cur_x).value;
- fill.mValue.y = (*cur_y).value;
- fill.mValue.z = (*cur_z).value;
-
- // subsample animation track
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- //SubsampleAnimTrack(out,cur_x, cur_y, cur_z, d, sample_delta);
- }
-
- if (cur_x != envl_x->keys.end()-1)
- ++cur_x;
- else end_x = true;
- if (cur_y != envl_y->keys.end()-1)
- ++cur_y;
- else end_y = true;
- if (cur_z != envl_z->keys.end()-1)
- ++cur_z;
- else end_z = true;
- }
-
- // Find key with lowest time value
- else if ((*cur_x).time <= (*cur_y).time && !end_x) {
-
- if ((*cur_z).time <= (*cur_x).time && !end_z) {
- InterpolateTrack(out,fill,(*cur_z).time);
- }
- else {
- InterpolateTrack(out,fill,(*cur_x).time);
- }
- }
- else if ((*cur_z).time <= (*cur_y).time && !end_z) {
- InterpolateTrack(out,fill,(*cur_z).time);
- }
- else if (!end_y) {
- // welcome on the server, y
- InterpolateTrack(out,fill,(*cur_y).time);
- }
- else {
- // we have reached the end of at least 2 channels,
- // only one is remaining. Extrapolate the 2.
- if (end_y) {
- InterpolateTrack(out,fill,(end_x ? (*cur_z) : (*cur_x)).time);
- }
- else if (end_x) {
- InterpolateTrack(out,fill,(end_z ? (*cur_y) : (*cur_z)).time);
- }
- else { // if (end_z)
- InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
- }
- }
- out.push_back(fill);
-
- if ( end_x && end_y && end_z ) /* finished? */
- break;
- }
-
- if (flags & AI_LWO_ANIM_FLAG_START_AT_ZERO) {
- for (std::vector<aiVectorKey>::iterator it = out.begin(); it != out.end(); ++it)
- (*it).mTime -= first;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract animation channel
-void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int /*flags = 0*/)
-{
- *out = NULL;
-
-
- //FIXME: crashes if more than one component is animated at different timings, to be resolved.
- return;
-
-#if 0
- // If we have no envelopes, return NULL
- if (envelopes.empty()) {
- return;
- }
-
- // We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
- const bool trans = (trans_x && trans_x->keys.size() > 1 || trans_y && trans_y->keys.size() > 1 || trans_z && trans_z->keys.size() > 1);
- const bool rotat = (rotat_x && rotat_x->keys.size() > 1 || rotat_y && rotat_y->keys.size() > 1 || rotat_z && rotat_z->keys.size() > 1);
- const bool scale = (scale_x && scale_x->keys.size() > 1 || scale_y && scale_y->keys.size() > 1 || scale_z && scale_z->keys.size() > 1);
- if (!trans && !rotat && !scale)
- return;
-
- // Allocate the output animation
- aiNodeAnim* anim = *out = new aiNodeAnim();
-
- // Setup default animation setup if necessary
- if (need_to_setup) {
- UpdateAnimRangeSetup();
- need_to_setup = false;
- }
-
- // copy translation keys
- if (trans) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,trans_x,trans_y,trans_z,flags);
-
- anim->mPositionKeys = new aiVectorKey[ anim->mNumPositionKeys = keys.size() ];
- std::copy(keys.begin(),keys.end(),anim->mPositionKeys);
- }
-
- // copy rotation keys
- if (rotat) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,rotat_x,rotat_y,rotat_z,flags);
-
- anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = keys.size() ];
-
- // convert heading, pitch, bank to quaternion
- for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
- aiQuatKey& qk = anim->mRotationKeys[i];
- qk.mTime = keys[i].mTime;
- qk.mValue = aiQuaternion( keys[i].mValue.x ,keys[i].mValue.z ,keys[i].mValue.y );
- }
- }
-
- // copy scaling keys
- if (scale) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,scale_x,scale_y,scale_z,flags);
-
- anim->mScalingKeys = new aiVectorKey[ anim->mNumScalingKeys = keys.size() ];
- std::copy(keys.begin(),keys.end(),anim->mScalingKeys);
- }
-#endif
-}
-
-
-#endif // no lwo or no lws
diff --git a/3rdparty/assimp/code/LWOAnimation.h b/3rdparty/assimp/code/LWOAnimation.h
deleted file mode 100644
index 0fa96691..00000000
--- a/3rdparty/assimp/code/LWOAnimation.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file LWOAnimation.h
- * @brief LWOAnimationResolver utility class
- *
- * This is for all lightwave-related file format, not only LWO.
- * LWS isthe main purpose.
-*/
-#ifndef AI_LWO_ANIMATION_INCLUDED
-#define AI_LWO_ANIMATION_INCLUDED
-
-namespace Assimp {
-namespace LWO {
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO envelopes
- */
-enum EnvelopeType
-{
- EnvelopeType_Position_X = 0x1,
- EnvelopeType_Position_Y = 0x2,
- EnvelopeType_Position_Z = 0x3,
-
- EnvelopeType_Rotation_Heading = 0x4,
- EnvelopeType_Rotation_Pitch = 0x5,
- EnvelopeType_Rotation_Bank = 0x6,
-
- EnvelopeType_Scaling_X = 0x7,
- EnvelopeType_Scaling_Y = 0x8,
- EnvelopeType_Scaling_Z = 0x9,
-
- // -- currently not yet handled
- EnvelopeType_Color_R = 0xa,
- EnvelopeType_Color_G = 0xb,
- EnvelopeType_Color_B = 0xc,
-
- EnvelopeType_Falloff_X = 0xd,
- EnvelopeType_Falloff_Y = 0xe,
- EnvelopeType_Falloff_Z = 0xf,
-
- EnvelopeType_Unknown
-};
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO interpolation modes
- */
-enum InterpolationType
-{
- IT_STEP, IT_LINE, IT_TCB, IT_HERM, IT_BEZI, IT_BEZ2
-};
-
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO pre or post range behaviours
- */
-enum PrePostBehaviour
-{
- PrePostBehaviour_Reset = 0x0,
- PrePostBehaviour_Constant = 0x1,
- PrePostBehaviour_Repeat = 0x2,
- PrePostBehaviour_Oscillate = 0x3,
- PrePostBehaviour_OffsetRepeat = 0x4,
- PrePostBehaviour_Linear = 0x5
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation keyframe
- */
-struct Key
-{
- Key()
- : inter (IT_LINE)
- {}
-
- //! Current time
- double time;
-
- //! Current value
- float value;
-
- //! How to interpolate this key with previous key?
- InterpolationType inter;
-
- //! Interpolation parameters
- float params[5];
-
-
- // for std::find()
- operator double () {
- return time;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation envelope
- */
-struct Envelope
-{
- Envelope()
- : type (EnvelopeType_Unknown)
- , pre (PrePostBehaviour_Constant)
- , post (PrePostBehaviour_Constant)
-
- , old_first (0)
- , old_last (0)
- {}
-
- //! Index of this envelope
- unsigned int index;
-
- //! Type of envelope
- EnvelopeType type;
-
- //! Pre and post-behaviour
- PrePostBehaviour pre,post;
-
- //! Keyframes for this envelope
- std::vector<Key> keys;
-
-
- // temporary data for AnimResolver
- size_t old_first,old_last;
-};
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_SAMPLE_ANIMS
-//! Flag for AnimResolver, subsamples the input data with the rate specified
-//! by AnimResolver::SetSampleRate().
-#define AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 0x1
-
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_START_AT_ZERO
-//! Flag for AnimResolver, ensures that the animations starts at zero.
-#define AI_LWO_ANIM_FLAG_START_AT_ZERO 0x2
-
-// ---------------------------------------------------------------------------
-/** @brief Utility class to build Assimp animations from LWO envelopes.
- *
- * Used for both LWO and LWS (MOT also).
- */
-class AnimResolver
-{
-public:
-
- // ------------------------------------------------------------------
- /** @brief Construct an AnimResolver from a given list of envelopes
- * @param envelopes Input envelopes. May be empty.
- * @param Output tick rate, per second
- * @note The input envelopes are possibly modified.
- */
- AnimResolver(std::list<Envelope>& envelopes,
- double tick);
-
-public:
-
- // ------------------------------------------------------------------
- /** @brief Extract the bind-pose transformation matrix.
- * @param out Receives bind-pose transformation matrix
- */
- void ExtractBindPose(aiMatrix4x4& out);
-
- // ------------------------------------------------------------------
- /** @brief Extract a node animation channel
- * @param out Receives a pointer to a newly allocated node anim.
- * If there's just one keyframe defined, *out is set to NULL and
- * no animation channel is computed.
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- */
- void ExtractAnimChannel(aiNodeAnim** out, unsigned int flags = 0);
-
-
- // ------------------------------------------------------------------
- /** @brief Set the sampling rate for ExtractAnimChannel().
- *
- * Non-linear interpolations are subsampled with this rate (keys
- * per second). Closer sampling positions, if existent, are kept.
- * The sampling rate defaults to 0, if this value is not changed and
- * AI_LWO_ANIM_FLAG_SAMPLE_ANIMS is specified for ExtractAnimChannel(),
- * the class finds a suitable sample rate by itself.
- */
- void SetSampleRate(double sr) {
- sample_rate = sr;
- }
-
- // ------------------------------------------------------------------
- /** @brief Getter for SetSampleRate()
- */
- double GetSampleRate() const {
- return sample_rate;
- }
-
- // ------------------------------------------------------------------
- /** @brief Set the animation time range
- *
- * @param first Time where the animation starts, in ticks
- * @param last Time where the animation ends, in ticks
- */
- void SetAnimationRange(double _first, double _last) {
- first = _first;
- last = _last;
-
- ClearAnimRangeSetup();
- UpdateAnimRangeSetup();
- }
-
-protected:
-
- // ------------------------------------------------------------------
- /** @brief Build linearly subsampled keys from 3 single envelopes
- * @param out Receives output keys
- * @param envl_x X-component envelope
- * @param envl_y Y-component envelope
- * @param envl_z Z-component envelope
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- * @note Up to two input envelopes may be NULL
- */
- void GetKeys(std::vector<aiVectorKey>& out,
- LWO::Envelope* envl_x,
- LWO::Envelope* envl_y,
- LWO::Envelope* envl_z,
- unsigned int flags);
-
- // ------------------------------------------------------------------
- /** @brief Resolve a single animation key by applying the right
- * interpolation to it.
- * @param cur Current key
- * @param envl Envelope working on
- * @param time time to be interpolated
- * @param fill Receives the interpolated output value.
- */
- void DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope* envl,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Almost the same, except we won't handle pre/post
- * conditions here.
- * @see DoInterpolation
- */
- void DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Interpolate 2 tracks if one is given
- *
- * @param out Receives extra output keys
- * @param key_out Primary output key
- * @param time Time to interpolate for
- */
- void InterpolateTrack(std::vector<aiVectorKey>& out,
- aiVectorKey& key_out,double time);
-
- // ------------------------------------------------------------------
- /** @brief Subsample an animation track by a given sampling rate
- *
- * @param out Receives output keys. Last key at input defines the
- * time where subsampling starts.
- * @param time Time to end subsampling at
- * @param sample_delta Time delta between two samples
- */
- void SubsampleAnimTrack(std::vector<aiVectorKey>& out,
- double time,double sample_delta);
-
- // ------------------------------------------------------------------
- /** @brief Delete all keys which we inserted to match anim setup
- */
- void ClearAnimRangeSetup();
-
- // ------------------------------------------------------------------
- /** @brief Insert extra keys to match LWO's pre and post behaviours
- * in a given time range [first...last]
- */
- void UpdateAnimRangeSetup();
-
-private:
- std::list<Envelope>& envelopes;
- double sample_rate;
-
- LWO::Envelope* trans_x, *trans_y, *trans_z;
- LWO::Envelope* rotat_x, *rotat_y, *rotat_z;
- LWO::Envelope* scale_x, *scale_y, *scale_z;
-
- double first, last;
- bool need_to_setup;
-
- // temporary storage
- LWO::Envelope* envl_x, * envl_y, * envl_z;
- std::vector<LWO::Key>::const_iterator cur_x,cur_y,cur_z;
- bool end_x, end_y, end_z;
-
- unsigned int flags;
- double sample_delta;
-};
-
-} // end namespace LWO
-} // end namespace Assimp
-
-#endif // !! AI_LWO_ANIMATION_INCLUDED
diff --git a/3rdparty/assimp/code/LWOBLoader.cpp b/3rdparty/assimp/code/LWOBLoader.cpp
deleted file mode 100644
index 339fcec5..00000000
--- a/3rdparty/assimp/code/LWOBLoader.cpp
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the LWO importer class for the older LWOB
- file formats, including materials */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// Internal headers
-#include "LWOLoader.h"
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBFile()
-{
- LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
- bool running = true;
- while (running)
- {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
- LE_NCONST IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- {
- throw DeadlyImportError("LWOB: Invalid chunk length");
- break;
- }
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- // vertex list
- case AI_LWO_PNTS:
- {
- if (!mCurLayer->mTempPoints.empty())
- DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice");
- else LoadLWOPoints(head->length);
- break;
- }
- // face list
- case AI_LWO_POLS:
- {
- if (!mCurLayer->mFaces.empty())
- DefaultLogger::get()->warn("LWO: POLS chunk encountered twice");
- else LoadLWOBPolygons(head->length);
- break;
- }
- // list of tags
- case AI_LWO_SRFS:
- {
- if (!mTags->empty())
- DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice");
- else LoadLWOTags(head->length);
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF:
- {
- LoadLWOBSurface(head->length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBPolygons(unsigned int length)
-{
- // first find out how many faces and vertices we'll finally need
- LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
- LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- // perform endianess conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- while (cursor < end)ByteSwap::Swap2(cursor++);
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-#endif
-
- unsigned int iNumFaces = 0,iNumVertices = 0;
- CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
-
- // allocate the output array and copy face indices
- if (iNumFaces)
- {
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces);
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWOB(it,cursor,end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
- LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
-{
- while (cursor < end && max--)
- {
- uint16_t numIndices = *cursor++;
- verts += numIndices;faces++;
- cursor += numIndices;
- int16_t surface = *cursor++;
- if (surface < 0)
- {
- // there are detail polygons
- numIndices = *cursor++;
- CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max)
-{
- while (cursor < end && max--)
- {
- LWO::Face& face = *it;++it;
- if ((face.mNumIndices = *cursor++))
- {
- if (cursor + face.mNumIndices >= end)break;
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- unsigned int & mi = face.mIndices[i] = *cursor++;
- if (mi > mCurLayer->mTempPoints.size())
- {
- DefaultLogger::get()->warn("LWOB: face index is out of range");
- mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
- }
- }
- }
- else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
- int16_t surface = *cursor++;
- if (surface < 0)
- {
- surface = -surface;
-
- // there are detail polygons.
- const uint16_t numPolygons = *cursor++;
- if (cursor < end)CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
- }
- face.surfaceIndex = surface-1;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
-{
- list.push_back(LWO::Texture());
- LWO::Texture* tex = &list.back();
-
- std::string type;
- GetS0(type,size);
- const char* s = type.c_str();
-
- if (strstr(s, "Image Map"))
- {
- // Determine mapping type
- if (strstr(s, "Planar"))
- tex->mapMode = LWO::Texture::Planar;
- else if (strstr(s, "Cylindrical"))
- tex->mapMode = LWO::Texture::Cylindrical;
- else if (strstr(s, "Spherical"))
- tex->mapMode = LWO::Texture::Spherical;
- else if (strstr(s, "Cubic"))
- tex->mapMode = LWO::Texture::Cubic;
- else if (strstr(s, "Front"))
- tex->mapMode = LWO::Texture::FrontProjection;
- }
- else
- {
- // procedural or gradient, not supported
- DefaultLogger::get()->error("LWOB: Unsupported legacy texture: " + type);
- }
-
- return tex;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBSurface(unsigned int size)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- mSurfaces->push_back( LWO::Surface () );
- LWO::Surface& surf = mSurfaces->back();
- LWO::Texture* pTex = NULL;
-
- GetS0(surf.mName,size);
- bool runnning = true;
- while (runnning) {
- if (mFileBuffer + 6 >= end)
- break;
-
- IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- /* A single test file (sonycam.lwo) seems to have invalid surface chunks.
- * I'm assuming it's the fault of a single, unknown exporter so there are
- * probably THOUSANDS of them. Here's a dirty workaround:
- *
- * We don't break if the chunk limit is exceeded. Instead, we're computing
- * how much storage is actually left and work with this value from now on.
- */
- if (mFileBuffer + head->length > end) {
- DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
- head->length = (uint16_t) (end - mFileBuffer);
- }
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- // diffuse color
- case AI_LWO_COLR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,3);
- surf.mColor.r = GetU1() / 255.0f;
- surf.mColor.g = GetU1() / 255.0f;
- surf.mColor.b = GetU1() / 255.0f;
- break;
- }
- // diffuse strength ...
- case AI_LWO_DIFF:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,2);
- surf.mDiffuseValue = GetU2() / 255.0f;
- break;
- }
- // specular strength ...
- case AI_LWO_SPEC:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,2);
- surf.mSpecularValue = GetU2() / 255.0f;
- break;
- }
- // luminosity ...
- case AI_LWO_LUMI:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LUMI,2);
- surf.mLuminosity = GetU2() / 255.0f;
- break;
- }
- // transparency
- case AI_LWO_TRAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,2);
- surf.mTransparency = GetU2() / 255.0f;
- break;
- }
- // surface flags
- case AI_LWO_FLAG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,FLAG,2);
- uint16_t flag = GetU2();
- if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
- if (flag & 0x8 ) surf.mColorHighlights = 1.f;
- if (flag & 0x100) surf.bDoubleSided = true;
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
- surf.mMaximumSmoothAngle = fabs( GetF4() );
- break;
- }
- // glossiness
- case AI_LWO_GLOS:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,2);
- surf.mGlossiness = (float)GetU2();
- break;
- }
- // color texture
- case AI_LWO_CTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mColorTextures,
- head->length);
- break;
- }
- // diffuse texture
- case AI_LWO_DTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
- head->length);
- break;
- }
- // specular texture
- case AI_LWO_STEX:
- {
- pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
- head->length);
- break;
- }
- // bump texture
- case AI_LWO_BTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mBumpTextures,
- head->length);
- break;
- }
- // transparency texture
- case AI_LWO_TTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
- head->length);
- break;
- }
- // texture path
- case AI_LWO_TIMG:
- {
- if (pTex) {
- GetS0(pTex->mFileName,head->length);
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
- break;
- }
- // texture strength
- case AI_LWO_TVAL:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
- if (pTex) {
- pTex->mStrength = (float)GetU1()/ 255.f;
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
- break;
- }
- // texture flags
- case AI_LWO_TFLG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TFLG,2);
-
- if (pTex)
- {
- const uint16_t s = GetU2();
- if (s & 1)
- pTex->majorAxis = LWO::Texture::AXIS_X;
- else if (s & 2)
- pTex->majorAxis = LWO::Texture::AXIS_Y;
- else if (s & 4)
- pTex->majorAxis = LWO::Texture::AXIS_Z;
-
- if (s & 16)
- DefaultLogger::get()->warn("LWOB: Ignoring \'negate\' flag on texture");
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TFLG chunk");
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/3rdparty/assimp/code/LWOFileData.h b/3rdparty/assimp/code/LWOFileData.h
deleted file mode 100644
index 562f2f3d..00000000
--- a/3rdparty/assimp/code/LWOFileData.h
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file LWOFileData.h
- * @brief Defines chunk constants used by the LWO file format
-
-The chunks are taken from the official LightWave SDK headers.
-
-*/
-#ifndef AI_LWO_FILEDATA_INCLUDED
-#define AI_LWO_FILEDATA_INCLUDED
-
-// STL headers
-#include <vector>
-#include <list>
-
-// public ASSIMP headers
-#include "../include/aiMesh.h"
-
-// internal headers
-#include "IFF.h"
-#include "LWOAnimation.h"
-
-namespace Assimp {
-namespace LWO {
-
-#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L','W','O','B')
-#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L','W','O','2')
-#define AI_LWO_FOURCC_LXOB AI_IFF_FOURCC('L','X','O','B')
-
-// chunks specific to the LWOB format
-#define AI_LWO_SRFS AI_IFF_FOURCC('S','R','F','S')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G')
-#define AI_LWO_VLUM AI_IFF_FOURCC('V','L','U','M')
-#define AI_LWO_VDIF AI_IFF_FOURCC('V','D','I','F')
-#define AI_LWO_VSPC AI_IFF_FOURCC('V','S','P','C')
-#define AI_LWO_RFLT AI_IFF_FOURCC('R','F','L','T')
-#define AI_LWO_BTEX AI_IFF_FOURCC('B','T','E','X')
-#define AI_LWO_CTEX AI_IFF_FOURCC('C','T','E','X')
-#define AI_LWO_DTEX AI_IFF_FOURCC('D','T','E','X')
-#define AI_LWO_LTEX AI_IFF_FOURCC('L','T','E','X')
-#define AI_LWO_RTEX AI_IFF_FOURCC('R','T','E','X')
-#define AI_LWO_STEX AI_IFF_FOURCC('S','T','E','X')
-#define AI_LWO_TTEX AI_IFF_FOURCC('T','T','E','X')
-#define AI_LWO_TFLG AI_IFF_FOURCC('T','F','L','G')
-#define AI_LWO_TSIZ AI_IFF_FOURCC('T','S','I','Z')
-#define AI_LWO_TCTR AI_IFF_FOURCC('T','C','T','R')
-#define AI_LWO_TFAL AI_IFF_FOURCC('T','F','A','L')
-#define AI_LWO_TVEL AI_IFF_FOURCC('T','V','E','L')
-#define AI_LWO_TCLR AI_IFF_FOURCC('T','C','L','R')
-#define AI_LWO_TVAL AI_IFF_FOURCC('T','V','A','L')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G')
-#define AI_LWO_TAAS AI_IFF_FOURCC('T','A','A','S')
-#define AI_LWO_TREF AI_IFF_FOURCC('T','R','E','F')
-#define AI_LWO_TOPC AI_IFF_FOURCC('T','O','P','C')
-#define AI_LWO_SDAT AI_IFF_FOURCC('S','D','A','T')
-#define AI_LWO_TFP0 AI_IFF_FOURCC('T','F','P','0')
-#define AI_LWO_TFP1 AI_IFF_FOURCC('T','F','P','1')
-
-
-/* top-level chunks */
-#define AI_LWO_LAYR AI_IFF_FOURCC('L','A','Y','R')
-#define AI_LWO_TAGS AI_IFF_FOURCC('T','A','G','S')
-#define AI_LWO_PNTS AI_IFF_FOURCC('P','N','T','S')
-#define AI_LWO_BBOX AI_IFF_FOURCC('B','B','O','X')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P')
-#define AI_LWO_VMAD AI_IFF_FOURCC('V','M','A','D')
-#define AI_LWO_POLS AI_IFF_FOURCC('P','O','L','S')
-#define AI_LWO_PTAG AI_IFF_FOURCC('P','T','A','G')
-#define AI_LWO_ENVL AI_IFF_FOURCC('E','N','V','L')
-#define AI_LWO_CLIP AI_IFF_FOURCC('C','L','I','P')
-#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F')
-#define AI_LWO_DESC AI_IFF_FOURCC('D','E','S','C')
-#define AI_LWO_TEXT AI_IFF_FOURCC('T','E','X','T')
-#define AI_LWO_ICON AI_IFF_FOURCC('I','C','O','N')
-
-/* polygon types */
-#define AI_LWO_FACE AI_IFF_FOURCC('F','A','C','E')
-#define AI_LWO_CURV AI_IFF_FOURCC('C','U','R','V')
-#define AI_LWO_PTCH AI_IFF_FOURCC('P','T','C','H')
-#define AI_LWO_MBAL AI_IFF_FOURCC('M','B','A','L')
-#define AI_LWO_BONE AI_IFF_FOURCC('B','O','N','E')
-#define AI_LWO_SUBD AI_IFF_FOURCC('S','U','B','D')
-
-/* polygon tags */
-#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F')
-#define AI_LWO_PART AI_IFF_FOURCC('P','A','R','T')
-#define AI_LWO_SMGP AI_IFF_FOURCC('S','M','G','P')
-
-/* envelopes */
-#define AI_LWO_PRE AI_IFF_FOURCC('P','R','E',' ')
-#define AI_LWO_POST AI_IFF_FOURCC('P','O','S','T')
-#define AI_LWO_KEY AI_IFF_FOURCC('K','E','Y',' ')
-#define AI_LWO_SPAN AI_IFF_FOURCC('S','P','A','N')
-#define AI_LWO_TCB AI_IFF_FOURCC('T','C','B',' ')
-#define AI_LWO_HERM AI_IFF_FOURCC('H','E','R','M')
-#define AI_LWO_BEZI AI_IFF_FOURCC('B','E','Z','I')
-#define AI_LWO_BEZ2 AI_IFF_FOURCC('B','E','Z','2')
-#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E')
-#define AI_LWO_STEP AI_IFF_FOURCC('S','T','E','P')
-
-/* clips */
-#define AI_LWO_STIL AI_IFF_FOURCC('S','T','I','L')
-#define AI_LWO_ISEQ AI_IFF_FOURCC('I','S','E','Q')
-#define AI_LWO_ANIM AI_IFF_FOURCC('A','N','I','M')
-#define AI_LWO_XREF AI_IFF_FOURCC('X','R','E','F')
-#define AI_LWO_STCC AI_IFF_FOURCC('S','T','C','C')
-#define AI_LWO_TIME AI_IFF_FOURCC('T','I','M','E')
-#define AI_LWO_CONT AI_IFF_FOURCC('C','O','N','T')
-#define AI_LWO_BRIT AI_IFF_FOURCC('B','R','I','T')
-#define AI_LWO_SATR AI_IFF_FOURCC('S','A','T','R')
-#define AI_LWO_HUE AI_IFF_FOURCC('H','U','E',' ')
-#define AI_LWO_GAMM AI_IFF_FOURCC('G','A','M','M')
-#define AI_LWO_NEGA AI_IFF_FOURCC('N','E','G','A')
-#define AI_LWO_IFLT AI_IFF_FOURCC('I','F','L','T')
-#define AI_LWO_PFLT AI_IFF_FOURCC('P','F','L','T')
-
-/* surfaces */
-#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R')
-#define AI_LWO_LUMI AI_IFF_FOURCC('L','U','M','I')
-#define AI_LWO_DIFF AI_IFF_FOURCC('D','I','F','F')
-#define AI_LWO_SPEC AI_IFF_FOURCC('S','P','E','C')
-#define AI_LWO_GLOS AI_IFF_FOURCC('G','L','O','S')
-#define AI_LWO_REFL AI_IFF_FOURCC('R','E','F','L')
-#define AI_LWO_RFOP AI_IFF_FOURCC('R','F','O','P')
-#define AI_LWO_RIMG AI_IFF_FOURCC('R','I','M','G')
-#define AI_LWO_RSAN AI_IFF_FOURCC('R','S','A','N')
-#define AI_LWO_TRAN AI_IFF_FOURCC('T','R','A','N')
-#define AI_LWO_TROP AI_IFF_FOURCC('T','R','O','P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G')
-#define AI_LWO_RIND AI_IFF_FOURCC('R','I','N','D')
-#define AI_LWO_TRNL AI_IFF_FOURCC('T','R','N','L')
-#define AI_LWO_BUMP AI_IFF_FOURCC('B','U','M','P')
-#define AI_LWO_SMAN AI_IFF_FOURCC('S','M','A','N')
-#define AI_LWO_SIDE AI_IFF_FOURCC('S','I','D','E')
-#define AI_LWO_CLRH AI_IFF_FOURCC('C','L','R','H')
-#define AI_LWO_CLRF AI_IFF_FOURCC('C','L','R','F')
-#define AI_LWO_ADTR AI_IFF_FOURCC('A','D','T','R')
-#define AI_LWO_SHRP AI_IFF_FOURCC('S','H','R','P')
-#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E')
-#define AI_LWO_LSIZ AI_IFF_FOURCC('L','S','I','Z')
-#define AI_LWO_ALPH AI_IFF_FOURCC('A','L','P','H')
-#define AI_LWO_AVAL AI_IFF_FOURCC('A','V','A','L')
-#define AI_LWO_GVAL AI_IFF_FOURCC('G','V','A','L')
-#define AI_LWO_BLOK AI_IFF_FOURCC('B','L','O','K')
-#define AI_LWO_VCOL AI_IFF_FOURCC('V','C','O','L')
-
-/* texture layer */
-#define AI_LWO_TYPE AI_IFF_FOURCC('T','Y','P','E')
-#define AI_LWO_CHAN AI_IFF_FOURCC('C','H','A','N')
-#define AI_LWO_NAME AI_IFF_FOURCC('N','A','M','E')
-#define AI_LWO_ENAB AI_IFF_FOURCC('E','N','A','B')
-#define AI_LWO_OPAC AI_IFF_FOURCC('O','P','A','C')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G')
-#define AI_LWO_PROJ AI_IFF_FOURCC('P','R','O','J')
-#define AI_LWO_STCK AI_IFF_FOURCC('S','T','C','K')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P')
-
-/* texture coordinates */
-#define AI_LWO_TMAP AI_IFF_FOURCC('T','M','A','P')
-#define AI_LWO_AXIS AI_IFF_FOURCC('A','X','I','S')
-#define AI_LWO_CNTR AI_IFF_FOURCC('C','N','T','R')
-#define AI_LWO_SIZE AI_IFF_FOURCC('S','I','Z','E')
-#define AI_LWO_ROTA AI_IFF_FOURCC('R','O','T','A')
-#define AI_LWO_OREF AI_IFF_FOURCC('O','R','E','F')
-#define AI_LWO_FALL AI_IFF_FOURCC('F','A','L','L')
-#define AI_LWO_CSYS AI_IFF_FOURCC('C','S','Y','S')
-
-/* image map */
-#define AI_LWO_IMAP AI_IFF_FOURCC('I','M','A','P')
-#define AI_LWO_IMAG AI_IFF_FOURCC('I','M','A','G')
-#define AI_LWO_WRAP AI_IFF_FOURCC('W','R','A','P')
-#define AI_LWO_WRPW AI_IFF_FOURCC('W','R','P','W')
-#define AI_LWO_WRPH AI_IFF_FOURCC('W','R','P','H')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P')
-#define AI_LWO_AAST AI_IFF_FOURCC('A','A','S','T')
-#define AI_LWO_PIXB AI_IFF_FOURCC('P','I','X','B')
-
-/* procedural */
-#define AI_LWO_PROC AI_IFF_FOURCC('P','R','O','C')
-#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R')
-#define AI_LWO_VALU AI_IFF_FOURCC('V','A','L','U')
-#define AI_LWO_FUNC AI_IFF_FOURCC('F','U','N','C')
-#define AI_LWO_FTPS AI_IFF_FOURCC('F','T','P','S')
-#define AI_LWO_ITPS AI_IFF_FOURCC('I','T','P','S')
-#define AI_LWO_ETPS AI_IFF_FOURCC('E','T','P','S')
-
-/* gradient */
-#define AI_LWO_GRAD AI_IFF_FOURCC('G','R','A','D')
-#define AI_LWO_GRST AI_IFF_FOURCC('G','R','S','T')
-#define AI_LWO_GREN AI_IFF_FOURCC('G','R','E','N')
-#define AI_LWO_PNAM AI_IFF_FOURCC('P','N','A','M')
-#define AI_LWO_INAM AI_IFF_FOURCC('I','N','A','M')
-#define AI_LWO_GRPT AI_IFF_FOURCC('G','R','P','T')
-#define AI_LWO_FKEY AI_IFF_FOURCC('F','K','E','Y')
-#define AI_LWO_IKEY AI_IFF_FOURCC('I','K','E','Y')
-
-/* shader */
-#define AI_LWO_SHDR AI_IFF_FOURCC('S','H','D','R')
-#define AI_LWO_DATA AI_IFF_FOURCC('D','A','T','A')
-
-
-/* VMAP types */
-#define AI_LWO_TXUV AI_IFF_FOURCC('T','X','U','V')
-#define AI_LWO_RGB AI_IFF_FOURCC('R','G','B',' ')
-#define AI_LWO_RGBA AI_IFF_FOURCC('R','G','B','A')
-#define AI_LWO_WGHT AI_IFF_FOURCC('W','G','H','T')
-
-#define AI_LWO_MNVW AI_IFF_FOURCC('M','N','V','W')
-#define AI_LWO_MORF AI_IFF_FOURCC('M','O','R','F')
-#define AI_LWO_SPOT AI_IFF_FOURCC('S','P','O','T')
-#define AI_LWO_PICK AI_IFF_FOURCC('P','I','C','K')
-
-// MODO extension - per-vertex normal vectors
-#define AI_LWO_MODO_NORM AI_IFF_FOURCC('N', 'O', 'R', 'M')
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a face in a LWO file
- *
- * \note We can't use the code in SmoothingGroups.inl here - the mesh
- * structures of 3DS/ASE and LWO are too different.
- */
-struct Face : public aiFace
-{
- //! Default construction
- Face()
- : surfaceIndex (0)
- , smoothGroup (0)
- , type (AI_LWO_FACE)
- {}
-
- //! Construction from given type
- Face(uint32_t _type)
- : surfaceIndex (0)
- , smoothGroup (0)
- , type (_type)
- {}
-
- //! Copy construction
- Face(const Face& f) : aiFace() {
- *this = f;
- }
-
- //! Zero-based index into tags chunk
- unsigned int surfaceIndex;
-
- //! Smooth group this face is assigned to
- unsigned int smoothGroup;
-
- //! Type of face
- uint32_t type;
-
-
- //! Assignment operator
- Face& operator=(const LWO::Face& f) {
- aiFace::operator =(f);
- surfaceIndex = f.surfaceIndex;
- smoothGroup = f.smoothGroup;
- type = f.type;
- return *this;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Base structure for all vertex map representations
- */
-struct VMapEntry
-{
- VMapEntry(unsigned int _dims)
- : dims(_dims)
- {}
-
- virtual ~VMapEntry() {}
-
- //! allocates memory for the vertex map
- virtual void Allocate(unsigned int num)
- {
- if (!rawData.empty())
- return; // return if already allocated
-
- const unsigned int m = num*dims;
- rawData.reserve(m + (m>>2u)); // 25% as extra storage for VMADs
- rawData.resize(m,0.f);
- abAssigned.resize(num,false);
- }
-
- std::string name;
- unsigned int dims;
-
- std::vector<float> rawData;
- std::vector<bool> abAssigned;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex color channel
- */
-struct VColorChannel : public VMapEntry
-{
- VColorChannel()
- : VMapEntry(4)
- {}
-
- //! need to overwrite this function - the alpha channel must
- //! be initialized to 1.0 by default
- virtual void Allocate(unsigned int num)
- {
- if (!rawData.empty())
- return; // return if already allocated
-
- register unsigned int m = num*dims;
- rawData.reserve(m + (m>>2u)); // 25% as extra storage for VMADs
- rawData.resize(m);
-
- for (aiColor4D* p = (aiColor4D*)&rawData[0]; p < (aiColor4D*)&rawData[m-1]; ++p)
- p->a = 1.f;
-
- abAssigned.resize(num,false);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex UV channel
- */
-struct UVChannel : public VMapEntry
-{
- UVChannel()
- : VMapEntry(2)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a weight map
- */
-struct WeightChannel : public VMapEntry
-{
- WeightChannel()
- : VMapEntry(1)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a vertex-normals channel (MODO extension)
- */
-struct NormalChannel : public VMapEntry
-{
- NormalChannel()
- : VMapEntry(3)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file texture
- */
-struct Texture
-{
- // we write the enum values out here to make debugging easier ...
- enum BlendType
- {
- Normal = 0,
- Subtractive = 1,
- Difference = 2,
- Multiply = 3,
- Divide = 4,
- Alpha = 5,
- TextureDispl = 6,
- Additive = 7
- };
-
- enum MappingMode
- {
- Planar = 0,
- Cylindrical = 1,
- Spherical = 2,
- Cubic = 3,
- FrontProjection = 4,
- UV = 5
- };
-
- enum Axes
- {
- AXIS_X = 0,
- AXIS_Y = 1,
- AXIS_Z = 2
- };
-
- enum Wrap
- {
- RESET = 0,
- REPEAT = 1,
- MIRROR = 2,
- EDGE = 3
- };
-
- Texture()
- : mClipIdx(0xffffffff)
- , mStrength (1.0f)
- , mUVChannelIndex ("unknown")
- , mRealUVIndex (0xffffffff)
- , enabled (true)
- , blendType (Additive)
- , bCanUse (true)
- , mapMode (UV)
- , majorAxis (AXIS_X)
- , wrapAmountH (1.0f)
- , wrapAmountW (1.0f)
- , wrapModeWidth (REPEAT)
- , wrapModeHeight (REPEAT)
- , ordinal ("\x00")
- {}
-
- //! File name of the texture
- std::string mFileName;
-
- //! Clip index
- unsigned int mClipIdx;
-
- //! Strength of the texture - blend factor
- float mStrength;
-
- uint32_t type; // type of the texture
-
- //! Name of the corresponding UV channel
- std::string mUVChannelIndex;
- unsigned int mRealUVIndex;
-
- //! is the texture enabled?
- bool enabled;
-
- //! blend type
- BlendType blendType;
-
- //! are we able to use the texture?
- bool bCanUse;
-
- //! mapping mode
- MappingMode mapMode;
-
- //! major axis for planar, cylindrical, spherical projections
- Axes majorAxis;
-
- //! wrap amount for cylindrical and spherical projections
- float wrapAmountH,wrapAmountW;
-
- //! wrapping mode for the texture
- Wrap wrapModeWidth,wrapModeHeight;
-
- //! ordinal string of the texture
- std::string ordinal;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file clip
- */
-struct Clip
-{
- enum Type
- {
- STILL, SEQ, REF, UNSUPPORTED
- } type;
-
- Clip()
- : type (UNSUPPORTED)
- , idx (0)
- , negate (false)
- {}
-
- //! path to the base texture -
- std::string path;
-
- //! reference to another CLIP
- unsigned int clipRef;
-
- //! index of the clip
- unsigned int idx;
-
- //! Negate the clip?
- bool negate;
-};
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file shader
- *
- * Later
- */
-struct Shader
-{
- Shader()
- : ordinal ("\x00")
- , functionName ("unknown")
- , enabled (true)
- {}
-
- std::string ordinal;
- std::string functionName;
- bool enabled;
-};
-
-typedef std::list < Texture > TextureList;
-typedef std::list < Shader > ShaderList;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file surface (= material)
- */
-struct Surface
-{
- Surface()
- : mColor (0.78431f,0.78431f,0.78431f)
- , bDoubleSided (false)
- , mDiffuseValue (1.f)
- , mSpecularValue (0.f)
- , mTransparency (0.f)
- , mGlossiness (0.4f)
- , mLuminosity (0.f)
- , mColorHighlights (0.f)
- , mMaximumSmoothAngle (0.f) // 0 == not specified, no smoothing
- , mVCMap ("")
- , mVCMapType (AI_LWO_RGBA)
- , mIOR (1.f) // vakuum
- , mBumpIntensity (1.f)
- , mWireframe (false)
- , mAdditiveTransparency (0.f)
- {}
-
- //! Name of the surface
- std::string mName;
-
- //! Color of the surface
- aiColor3D mColor;
-
- //! true for two-sided materials
- bool bDoubleSided;
-
- //! Various material parameters
- float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness,mLuminosity,mColorHighlights;
-
- //! Maximum angle between two adjacent triangles
- //! that they can be smoothed - in degrees
- float mMaximumSmoothAngle;
-
- //! Vertex color map to be used to color the surface
- std::string mVCMap;
- uint32_t mVCMapType;
-
- //! Names of the special shaders to be applied to the surface
- ShaderList mShaders;
-
- //! Textures - the first entry in the list is evaluated first
- TextureList mColorTextures, // color textures are added to both diffuse and specular texture stacks
- mDiffuseTextures,
- mSpecularTextures,
- mOpacityTextures,
- mBumpTextures,
- mGlossinessTextures,
- mReflectionTextures;
-
- //! Index of refraction
- float mIOR;
-
- //! Bump intensity scaling
- float mBumpIntensity;
-
- //! Wireframe flag
- bool mWireframe;
-
- //! Intensity of additive blending
- float mAdditiveTransparency;
-};
-
-// ---------------------------------------------------------------------------
-#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
- if (length < size) \
- { \
- throw DeadlyImportError("LWO: "#name" chunk is too small"); \
- } \
-
-
-// some typedefs ... to make life with loader monsters like this easier
-typedef std::vector < aiVector3D > PointList;
-typedef std::vector < LWO::Face > FaceList;
-typedef std::vector < LWO::Surface > SurfaceList;
-typedef std::vector < std::string > TagList;
-typedef std::vector < unsigned int > TagMappingTable;
-typedef std::vector < unsigned int > ReferrerList;
-typedef std::vector < WeightChannel > WeightChannelList;
-typedef std::vector < VColorChannel > VColorChannelList;
-typedef std::vector < UVChannel > UVChannelList;
-typedef std::vector < Clip > ClipList;
-typedef std::vector < Envelope > EnvelopeList;
-typedef std::vector < unsigned int > SortedRep;
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a layer in the file
- */
-struct Layer
-{
- Layer()
- : mFaceIDXOfs (0)
- , mPointIDXOfs (0)
- , mParent (0x0)
- , mIndex (0xffff)
- , skip (false)
- {}
-
- /** Temporary point list from the file */
- PointList mTempPoints;
-
- /** Lists for every point the index of another point
- that has been copied from *this* point or 0xffffffff if
- no copy of the point has been made */
- ReferrerList mPointReferrers;
-
- /** Weight channel list from the file */
- WeightChannelList mWeightChannels;
-
- /** Subdivision weight channel list from the file */
- WeightChannelList mSWeightChannels;
-
- /** Vertex color list from the file */
- VColorChannelList mVColorChannels;
-
- /** UV channel list from the file */
- UVChannelList mUVChannels;
-
- /** Normal vector channel from the file */
- NormalChannel mNormals;
-
- /** Temporary face list from the file*/
- FaceList mFaces;
-
- /** Current face indexing offset from the beginning of the buffers*/
- unsigned int mFaceIDXOfs;
-
- /** Current point indexing offset from the beginning of the buffers*/
- unsigned int mPointIDXOfs;
-
- /** Parent index */
- uint16_t mParent;
-
- /** Index of the layer */
- uint16_t mIndex;
-
- /** Name of the layer */
- std::string mName;
-
- /** Pivot point of the layer */
- aiVector3D mPivot;
-
- /** Skip this layer? */
- bool skip;
-};
-
-typedef std::list<LWO::Layer> LayerList;
-
-
-}}
-
-
-#endif // !! AI_LWO_FILEDATA_INCLUDED
-
diff --git a/3rdparty/assimp/code/LWOLoader.cpp b/3rdparty/assimp/code/LWOLoader.cpp
deleted file mode 100644
index b19ffe69..00000000
--- a/3rdparty/assimp/code/LWOLoader.cpp
+++ /dev/null
@@ -1,1403 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file LWOLoader.cpp
- * @brief Implementation of the LWO importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "LWOLoader.h"
-#include "MaterialSystem.h"
-#include "StringComparison.h"
-#include "SGSpatialSort.h"
-#include "ByteSwap.h"
-#include "ProcessHelper.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LWOImporter::LWOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LWOImporter::~LWOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "lwo" || extension == "lxo")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[3];
- tokens[0] = AI_LWO_FOURCC_LWOB;
- tokens[1] = AI_LWO_FOURCC_LWO2;
- tokens[2] = AI_LWO_FOURCC_LXOB;
- return CheckMagicToken(pIOHandler,pFile,tokens,3,8);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void LWOImporter::SetupProperties(const Importer* pImp)
-{
- configSpeedFlag = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0) ? true : false);
- configLayerIndex = pImp->GetPropertyInteger (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,0xffffffff);
- configLayerName = pImp->GetPropertyString (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,"");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void LWOImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open LWO file " + pFile + ".");
-
- if ((this->fileSize = (unsigned int)file->FileSize()) < 12)
- throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector< uint8_t > mBuffer(fileSize);
- file->Read( &mBuffer[0], 1, fileSize);
- this->pScene = pScene;
-
- // Determine the type of the file
- uint32_t fileType;
- const char* sz = IFF::ReadHeader(&mBuffer[0],fileType);
- if (sz)throw DeadlyImportError(sz);
-
- mFileBuffer = &mBuffer[0] + 12;
- fileSize -= 12;
-
- // Initialize some members with their default values
- hasNamedLayer = false;
-
- // Create temporary storage on the stack but store pointers to it in the class
- // instance. Therefore everything will be destructed properly if an exception
- // is thrown and we needn't take care of that.
- LayerList _mLayers;
- SurfaceList _mSurfaces;
- TagList _mTags;
- TagMappingTable _mMapping;
-
- mLayers = &_mLayers;
- mTags = &_mTags;
- mMapping = &_mMapping;
- mSurfaces = &_mSurfaces;
-
- // Allocate a default layer (layer indices are 1-based from now)
- mLayers->push_back(Layer());
- mCurLayer = &mLayers->back();
- mCurLayer->mName = "<LWODefault>";
-
- // old lightwave file format (prior to v6)
- if (AI_LWO_FOURCC_LWOB == fileType) {
- DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
-
- mIsLWO2 = false;
- mIsLXOB = false;
- LoadLWOBFile();
- }
- // New lightwave format
- else if (AI_LWO_FOURCC_LWO2 == fileType) {
- mIsLXOB = false;
- DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
- }
- // MODO file format
- else if (AI_LWO_FOURCC_LXOB == fileType) {
- mIsLXOB = true;
- DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
- }
- // we don't know this format
- else
- {
- char szBuff[5];
- szBuff[0] = (char)(fileType >> 24u);
- szBuff[1] = (char)(fileType >> 16u);
- szBuff[2] = (char)(fileType >> 8u);
- szBuff[3] = (char)(fileType);
- szBuff[4] = '\0';
- throw DeadlyImportError(std::string("Unknown LWO sub format: ") + szBuff);
- }
-
- if (AI_LWO_FOURCC_LWOB != fileType) {
- mIsLWO2 = true;
- LoadLWO2File();
-
- // The newer lightwave format allows the user to configure the
- // loader that just one layer is used. If this is the case
- // we need to check now whether the requested layer has been found.
- if (0xffffffff != configLayerIndex && configLayerIndex > mLayers->size())
- throw DeadlyImportError("LWO2: The requested layer was not found");
-
- if (configLayerName.length() && !hasNamedLayer) {
- throw DeadlyImportError("LWO2: Unable to find the requested layer: "
- + configLayerName);
- }
- }
-
- // now, as we have loaded all data, we can resolve cross-referenced tags and clips
- ResolveTags();
- ResolveClips();
-
- // now process all layers and build meshes and nodes
- std::vector<aiMesh*> apcMeshes;
- std::vector<aiNode*> apcNodes;
- apcNodes. reserve(mLayers->size());
- apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
-
- unsigned int iDefaultSurface = 0xffffffff; // index of the default surface
- for (LayerList::iterator lit = mLayers->begin(), lend = mLayers->end();lit != lend;++lit) {
- LWO::Layer& layer = *lit;
- if (layer.skip)
- continue;
-
- // I don't know whether there could be dummy layers, but it would be possible
- const unsigned int meshStart = (unsigned int)apcMeshes.size();
- if (!layer.mFaces.empty() && !layer.mTempPoints.empty()) {
-
- // now sort all faces by the surfaces assigned to them
- std::vector<SortedRep> pSorted(mSurfaces->size()+1);
-
- unsigned int i = 0;
- for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end();it != end;++it,++i) {
- // Check whether we support this face's type
- if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH &&
- (*it).type != AI_LWO_BONE && (*it).type != AI_LWO_SUBD) {
- continue;
- }
-
- unsigned int idx = (*it).surfaceIndex;
- if (idx >= mTags->size())
- {
- DefaultLogger::get()->warn("LWO: Invalid face surface index");
- idx = 0xffffffff;
- }
- if (0xffffffff == idx || 0xffffffff == (idx = _mMapping[idx])) {
- if (0xffffffff == iDefaultSurface) {
- iDefaultSurface = (unsigned int)mSurfaces->size();
- mSurfaces->push_back(LWO::Surface());
- LWO::Surface& surf = mSurfaces->back();
- surf.mColor.r = surf.mColor.g = surf.mColor.b = 0.6f;
- surf.mName = "LWODefaultSurface";
- }
- idx = iDefaultSurface;
- }
- pSorted[idx].push_back(i);
- }
- if (0xffffffff == iDefaultSurface) {
- pSorted.erase(pSorted.end()-1);
- }
- for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) {
- SortedRep& sorted = pSorted[i];
- if (sorted.empty())
- continue;
-
- // generate the mesh
- aiMesh* mesh = new aiMesh();
- apcMeshes.push_back(mesh);
- mesh->mNumFaces = (unsigned int)sorted.size();
-
- // count the number of vertices
- SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
- for (;it != end;++it) {
- mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
- }
-
- aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiFace* pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
- mesh->mMaterialIndex = i;
-
- // find out which vertex color channels and which texture coordinate
- // channels are really required by the material attached to this mesh
- unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS];
-
-#if _DEBUG
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui )
- vUVChannelIndices[mui] = 0xffffffff;
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui )
- vVColorIndices[mui] = 0xffffffff;
-#endif
-
- FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices);
- FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices);
-
- // allocate storage for UV and CV channels
- aiVector3D* pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
- if (0xffffffff == vUVChannelIndices[mui])
- break;
-
- pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
-
- // LightWave doesn't support more than 2 UV components (?)
- mesh->mNumUVComponents[0] = 2;
- }
-
- if (layer.mNormals.name.length())
- nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui) {
- if (0xffffffff == vVColorIndices[mui])break;
- pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
- }
-
- // we would not need this extra array, but the code is much cleaner if we use it
- std::vector<unsigned int>& smoothingGroups = layer.mPointReferrers;
- smoothingGroups.erase (smoothingGroups.begin(),smoothingGroups.end());
- smoothingGroups.resize(mesh->mNumFaces,0);
-
- // now convert all faces
- unsigned int vert = 0;
- std::vector<unsigned int>::iterator outIt = smoothingGroups.begin();
- for (it = sorted.begin(); it != end;++it,++outIt) {
- const LWO::Face& face = layer.mFaces[*it];
- *outIt = face.smoothGroup;
-
- // copy all vertices
- for (unsigned int q = 0; q < face.mNumIndices;++q,++vert) {
- register unsigned int idx = face.mIndices[q];
- *pv++ = layer.mTempPoints[idx] /*- layer.mPivot*/;
-
- // process UV coordinates
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w) {
- if (0xffffffff == vUVChannelIndices[w])
- break;
- aiVector3D*& pp = pvUV[w];
- const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
- pp->x = src.x;
- pp->y = src.y;
- pp++;
- }
-
- // process normals (MODO extension)
- if (nrm) {
- *nrm = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
- nrm->z *= -1.f;
- ++nrm;
- }
-
- // process vertex colors
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w) {
- if (0xffffffff == vVColorIndices[w])
- break;
- *pvVC[w] = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
-
- // If a RGB color map is explicitly requested delete the
- // alpha channel - it could theoretically be != 1.
- if (_mSurfaces[i].mVCMapType == AI_LWO_RGB)
- pvVC[w]->a = 1.f;
-
- pvVC[w]++;
- }
-
-#if 0
- // process vertex weights. We can't properly reconstruct the whole skeleton for now,
- // but we can create dummy bones for all weight channels which we have.
- for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
- {
- }
-#endif
-
- face.mIndices[q] = vert;
- }
- pf->mIndices = face.mIndices;
- pf->mNumIndices = face.mNumIndices;
- unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
- pf++;
- }
-
- if (!mesh->mNormals) {
- // Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
- // Step here since it wouldn't handle smoothing groups correctly for LWO.
- // So we use a separate implementation.
- ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
- }
- else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
- ++p;
- }
- }
-
- // Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
- unsigned int num = apcMeshes.size() - meshStart;
- if (layer.mName != "<LWODefault>" || num > 0) {
- aiNode* pcNode = new aiNode();
- apcNodes.push_back(pcNode);
- pcNode->mName.Set(layer.mName);
- pcNode->mParent = (aiNode*)&layer;
- pcNode->mNumMeshes = num;
-
- if (pcNode->mNumMeshes) {
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- for (unsigned int p = 0; p < pcNode->mNumMeshes;++p)
- pcNode->mMeshes[p] = p + meshStart;
- }
- }
- }
-
- if (apcNodes.empty() || apcMeshes.empty())
- throw DeadlyImportError("LWO: No meshes loaded");
-
- // The RemoveRedundantMaterials step will clean this up later
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
- for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat) {
- MaterialHelper* pcMat = new MaterialHelper();
- pScene->mMaterials[mat] = pcMat;
- ConvertMaterial((*mSurfaces)[mat],pcMat);
- }
-
- // copy the meshes to the output structure
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ];
- ::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*));
-
- // generate the final node graph
- GenerateNodeGraph(apcNodes);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
- const LWO::Surface& surface)
-{
- // Allocate output storage
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- // First generate per-face normals
- aiVector3D* out;
- std::vector<aiVector3D> faceNormals;
-
- // ... in some cases that's already enough
- if (!surface.mMaximumSmoothAngle)
- out = mesh->mNormals;
- else {
- faceNormals.resize(mesh->mNumVertices);
- out = &faceNormals[0];
- }
-
- aiFace* begin = mesh->mFaces, *const end = mesh->mFaces+mesh->mNumFaces;
- for (; begin != end; ++begin) {
- aiFace& face = *begin;
-
- // LWO doc: "the normal is defined as the cross product of the first and last edges"
- aiVector3D* pV1 = mesh->mVertices + face.mIndices[0];
- aiVector3D* pV2 = mesh->mVertices + face.mIndices[1];
- aiVector3D* pV3 = mesh->mVertices + face.mIndices[face.mNumIndices-1];
-
- aiVector3D vNor = ((*pV2 - *pV1) ^(*pV3 - *pV1)).Normalize();
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- out[face.mIndices[i]] = vNor;
- }
- if (!surface.mMaximumSmoothAngle)return;
- const float posEpsilon = ComputePositionEpsilon(mesh);
-
- // Now generate the spatial sort tree
- SGSpatialSort sSort;
- std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
- for ( begin = mesh->mFaces; begin != end; ++begin, ++it)
- {
- aiFace& face = *begin;
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- register unsigned int tt = face.mIndices[i];
- sSort.Add(mesh->mVertices[tt],tt,*it);
- }
- }
- // Sort everything - this takes O(nlogn) time
- sSort.Prepare();
- std::vector<unsigned int> poResult;
- poResult.reserve(20);
-
- // Generate vertex normals. We have O(logn) for the binary lookup, which we need
- // for n elements, thus the EXPECTED complexity is O(nlogn)
- if (surface.mMaximumSmoothAngle < 3.f && !configSpeedFlag) {
- const float fLimit = cos(surface.mMaximumSmoothAngle);
-
- for ( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace& face = *begin;
- unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx)
- {
- register unsigned int idx = *beginIdx;
- sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
- std::vector<unsigned int>::const_iterator a, end = poResult.end();
-
- aiVector3D vNormals;
- for (a = poResult.begin();a != end;++a) {
- const aiVector3D& v = faceNormals[*a];
- if (v * faceNormals[idx] < fLimit)
- continue;
- vNormals += v;
- }
- mesh->mNormals[idx] = vNormals.Normalize();
- }
- }
- }
- // faster code path in case there is no smooth angle
- else {
- std::vector<bool> vertexDone(mesh->mNumVertices,false);
- for ( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace& face = *begin;
- unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx)
- {
- register unsigned int idx = *beginIdx;
- if (vertexDone[idx])
- continue;
- sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
- std::vector<unsigned int>::const_iterator a, end = poResult.end();
-
- aiVector3D vNormals;
- for (a = poResult.begin();a != end;++a) {
- const aiVector3D& v = faceNormals[*a];
- vNormals += v;
- }
- vNormals.Normalize();
- for (a = poResult.begin();a != end;++a) {
- mesh->mNormals[*a] = vNormals;
- vertexDone[*a] = true;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::AddChildren(aiNode* node, uint16_t parent, std::vector<aiNode*>& apcNodes)
-{
- for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
- if (*it) {
- LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
- if (layer->mParent == parent && layer->mIndex != parent)
- ++node->mNumChildren;
- }
- }
-
- if (node->mNumChildren) {
- unsigned int p = 0;
-
- node->mChildren = new aiNode* [ node->mNumChildren ];
- for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
- if (*it) {
- LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
- if (layer->mParent == parent && layer->mIndex != parent) {
- aiNode* nd = node->mChildren[p++] = *it;
- nd->mParent = node;
-
- // fixme: ignore pivot points for the moment
- //nd->mTransformation.a4 = layer->mPivot.x;
- //nd->mTransformation.b4 = layer->mPivot.y;
- //nd->mTransformation.c4 = layer->mPivot.z;
-
- // recursively add more children
- (*it) = NULL;
- AddChildren(nd,layer->mIndex,apcNodes);
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
-{
- // now generate the final nodegraph - generate a root node and attach children
- aiNode* root = pScene->mRootNode = new aiNode();
- root->mName.Set("<LWORoot>");
- AddChildren(root,0,apcNodes);
-
- // check whether we added all layers with meshes assigned to the output graph.
- // if not, add them to the root node
- unsigned int extra = 0;
- for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
- if ((*it) && (*it)->mNumMeshes)
- ++extra;
- }
-
- if (extra) {
- const unsigned int newSize = extra + pScene->mRootNode->mNumChildren;
- aiNode** const apcNewNodes = new aiNode*[newSize];
- if ((extra = root->mNumChildren))
- ::memcpy(apcNewNodes,root->mChildren,extra*sizeof(void*));
-
- aiNode** cc = apcNewNodes+extra;
- for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
- if ((*it) && (*it)->mNumMeshes) {
- aiNode* nd = *cc++ = *it;
- nd->mParent = pScene->mRootNode;
-
- // recursively add more children
- (*it) = NULL;
- AddChildren(nd,((LWO::Layer*)nd->mParent)->mIndex,apcNodes);
- }
- }
- delete[] root->mChildren;
- root->mChildren = apcNewNodes;
- root->mNumChildren = newSize;
- }
- if (!pScene->mRootNode->mNumChildren)
- throw DeadlyImportError("LWO: Unable to build a valid node graph");
-
- // Remove a single root node with no meshes assigned to it ...
- if (1 == pScene->mRootNode->mNumChildren) {
- aiNode* pc = pScene->mRootNode->mChildren[0];
- pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
- delete pScene->mRootNode;
- pScene->mRootNode = pc;
- }
-
- // convert the whole stuff to RH with CCW winding
- MakeLeftHandedProcess maker;
- maker.Execute(pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveTags()
-{
- // --- this function is used for both LWO2 and LWOB
- mMapping->resize(mTags->size(),0xffffffff);
- for (unsigned int a = 0; a < mTags->size();++a) {
-
- const std::string& c = (*mTags)[a];
- for (unsigned int i = 0; i < mSurfaces->size();++i) {
-
- const std::string& d = (*mSurfaces)[i].mName;
- if (!ASSIMP_stricmp(c,d)) {
-
- (*mMapping)[a] = i;
- break;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveClips()
-{
- for ( unsigned int i = 0; i < mClips.size();++i) {
-
- Clip& clip = mClips[i];
- if (Clip::REF == clip.type) {
-
- if (clip.clipRef >= mClips.size()) {
- DefaultLogger::get()->error("LWO2: Clip referrer index is out of range");
- clip.clipRef = 0;
- }
-
- Clip& dest = mClips[clip.clipRef];
- if (Clip::REF == dest.type) {
- DefaultLogger::get()->error("LWO2: Clip references another clip reference");
- clip.type = Clip::UNSUPPORTED;
- }
-
- else {
- clip.path = dest.path;
- clip.type = dest.type;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::AdjustTexturePath(std::string& out)
-{
- // --- this function is used for both LWO2 and LWOB
- if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
-
- // remove the (sequence) and append 000
- DefaultLogger::get()->info("LWOB: Sequence of animated texture found. It will be ignored");
- out = out.substr(0,out.length()-10) + "000";
- }
-
- // format: drive:path/file - we just need to insert a slash after the drive
- std::string::size_type n = out.find_first_of(':');
- if (std::string::npos != n) {
- out.insert(n+1,"/");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOTags(unsigned int size)
-{
- // --- this function is used for both LWO2 and LWOB
-
- const char* szCur = (const char*)mFileBuffer, *szLast = szCur;
- const char* const szEnd = szLast+size;
- while (szCur < szEnd)
- {
- if (!(*szCur))
- {
- const size_t len = (size_t)(szCur-szLast);
- // FIX: skip empty-sized tags
- if (len)
- mTags->push_back(std::string(szLast,len));
- szCur += (len&0x1 ? 1 : 2);
- szLast = szCur;
- }
- szCur++;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOPoints(unsigned int length)
-{
- // --- this function is used for both LWO2 and LWOB but for
- // LWO2 we need to allocate 25% more storage - it could be we'll
- // need to duplicate some points later.
- register unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
- if (mIsLWO2)
- {
- mCurLayer->mTempPoints.reserve ( regularSize + (regularSize>>2u) );
- mCurLayer->mTempPoints.resize ( regularSize );
-
- // initialize all point referrers with the default values
- mCurLayer->mPointReferrers.reserve ( regularSize + (regularSize>>2u) );
- mCurLayer->mPointReferrers.resize ( regularSize, 0xffffffff );
- }
- else mCurLayer->mTempPoints.resize( regularSize );
-
- // perform endianess conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- for (unsigned int i = 0; i < length>>2;++i)
- ByteSwap::Swap4( mFileBuffer + (i << 2));
-#endif
- ::memcpy(&mCurLayer->mTempPoints[0],mFileBuffer,length);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Polygons(unsigned int length)
-{
- LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
- const uint32_t type = GetU4();
-
- // Determine the type of the polygons
- switch (type)
- {
- // read unsupported stuff too (although we wont process it)
- case AI_LWO_MBAL:
- DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (METABALL)");
- break;
- case AI_LWO_CURV:
- DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
- break;
-
- // These are ok with no restrictions
- case AI_LWO_PTCH:
- case AI_LWO_FACE:
- case AI_LWO_BONE:
- case AI_LWO_SUBD:
- break;
- default:
-
- // hm!? wtf is this? ok ...
- DefaultLogger::get()->error("LWO2: Ignoring unknown polygon type.");
- break;
- }
-
- // first find out how many faces and vertices we'll finally need
- uint16_t* cursor= (uint16_t*)mFileBuffer;
-
- unsigned int iNumFaces = 0,iNumVertices = 0;
- CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end);
-
- // allocate the output array and copy face indices
- if (iNumFaces) {
- cursor = (uint16_t*)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces,LWO::Face(type));
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWO2(it,cursor,end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& faces,
- uint16_t*& cursor, const uint16_t* const end, unsigned int max)
-{
- while (cursor < end && max--)
- {
- AI_LSWAP2P(cursor);
- uint16_t numIndices = *cursor++;
- numIndices &= 0x03FF;
- verts += numIndices;++faces;
-
- for (uint16_t i = 0; i < numIndices; i++)
- ReadVSizedIntLWO2((uint8_t*&)cursor);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
- uint16_t*& cursor,
- const uint16_t* const end)
-{
- while (cursor < end) {
-
- LWO::Face& face = *it++;;
- if ((face.mNumIndices = (*cursor++) & 0x03FF)) /* byte swapping has already been done */ {
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices; i++)
- {
- face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs;
- if (face.mIndices[i] > mCurLayer->mTempPoints.size())
- {
- DefaultLogger::get()->warn("LWO2: Failure evaluating face record, index is out of range");
- face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size()-1;
- }
- }
- }
- else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
-{
- LE_NCONST uint8_t* const end = mFileBuffer+length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,PTAG,4);
- uint32_t type = GetU4();
-
- if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
- return;
-
- while (mFileBuffer < end) {
-
- unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- unsigned int j = GetU2();
-
- if (i >= mCurLayer->mFaces.size()) {
- DefaultLogger::get()->warn("LWO2: face index in PTAG is out of range");
- continue;
- }
-
- switch (type) {
-
- case AI_LWO_SURF:
- mCurLayer->mFaces[i].surfaceIndex = j;
- break;
- case AI_LWO_SMGP: /* is that really used? */
- mCurLayer->mFaces[i].smoothGroup = j;
- break;
- };
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
-{
- for (typename std::vector< T >::iterator it = list.begin(), end = list.end();it != end; ++it) {
- if ((*it).name == name) {
- if (!perPoly) {
- DefaultLogger::get()->warn("LWO2: Found two VMAP sections with equal names");
- }
- return &(*it);
- }
- }
- list.push_back( T() );
- VMapEntry* p = &list.back();
- p->name = name;
- return p;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(T& chan, unsigned int srcIdx)
-{
- if (!chan.name.length())
- return;
-
- chan.abAssigned[srcIdx] = true;
- chan.abAssigned.resize(chan.abAssigned.size()+1,false);
-
- for (unsigned int a = 0; a < chan.dims;++a)
- chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
-{
- for (typename std::vector< T >::iterator it = list.begin(), end = list.end();it != end;++it) {
- CreateNewEntry( *it, srcIdx );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead,
- unsigned int idx, float* data)
-{
- ai_assert(NULL != data);
- LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
- unsigned int i;
-
- base->abAssigned[idx] = true;
- for (i = 0; i < numRead;++i) {
- base->rawData[idx*base->dims+i]= data[i];
- }
-
- if (0xffffffff != (i = refList[idx])) {
- DoRecursiveVMAPAssignment(base,numRead,i,data);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
-{
- if (0xffffffff == refList[srcIdx]) {
- refList[srcIdx] = destIdx;
- return;
- }
- AddToSingleLinkedList(refList,refList[srcIdx],destIdx);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 vertex map
-void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
-{
- LE_NCONST uint8_t* const end = mFileBuffer+length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,VMAP,6);
- unsigned int type = GetU4();
- unsigned int dims = GetU2();
-
- VMapEntry* base;
-
- // read the name of the vertex map
- std::string name;
- GetS0(name,length);
-
- switch (type)
- {
- case AI_LWO_TXUV:
- if (dims != 2) {
- DefaultLogger::get()->warn("LWO2: Skipping UV channel \'"
- + name + "\' with !2 components");
- return;
- }
- base = FindEntry(mCurLayer->mUVChannels,name,perPoly);
- break;
- case AI_LWO_WGHT:
- case AI_LWO_MNVW:
- if (dims != 1) {
- DefaultLogger::get()->warn("LWO2: Skipping Weight Channel \'"
- + name + "\' with !1 components");
- return;
- }
- base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels
- : mCurLayer->mSWeightChannels),name,perPoly);
- break;
- case AI_LWO_RGB:
- case AI_LWO_RGBA:
- if (dims != 3 && dims != 4) {
- DefaultLogger::get()->warn("LWO2: Skipping Color Map \'"
- + name + "\' with a dimension > 4 or < 3");
- return;
- }
- base = FindEntry(mCurLayer->mVColorChannels,name,perPoly);
- break;
-
- case AI_LWO_MODO_NORM:
- /* This is a non-standard extension chunk used by Luxology's MODO.
- * It stores per-vertex normals. This VMAP exists just once, has
- * 3 dimensions and is btw extremely beautiful.
- */
- if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
- return;
-
- DefaultLogger::get()->info("Processing non-standard extension: MODO VMAP.NORM.vert_normals");
-
- mCurLayer->mNormals.name = name;
- base = & mCurLayer->mNormals;
- break;
-
- case AI_LWO_PICK: /* these VMAPs are just silently dropped */
- case AI_LWO_MORF:
- case AI_LWO_SPOT:
- return;
-
- default:
- if (name == "APS.Level") {
- // XXX handle this (seems to be subdivision-related).
- }
- DefaultLogger::get()->warn("LWO2: Skipping unknown VMAP/VMAD channel \'" + name + "\'");
- return;
- };
- base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
-
- // now read all entries in the map
- type = std::min(dims,base->dims);
- const unsigned int diff = (dims - type)<<2u;
-
- LWO::FaceList& list = mCurLayer->mFaces;
- LWO::PointList& pointList = mCurLayer->mTempPoints;
- LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
-
- float temp[4];
-
- const unsigned int numPoints = (unsigned int)pointList.size();
- const unsigned int numFaces = (unsigned int)list.size();
-
- while (mFileBuffer < end) {
-
- unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
- if (idx >= numPoints) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAP/VMAD entry \'" + name + "\', vertex index is out of range");
- mFileBuffer += base->dims<<2u;
- continue;
- }
- if (perPoly) {
- unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- if (base->abAssigned[idx]) {
- // we have already a VMAP entry for this vertex - thus
- // we need to duplicate the corresponding polygon.
- if (polyIdx >= numFaces) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', polygon index is out of range");
- mFileBuffer += base->dims<<2u;
- continue;
- }
-
- LWO::Face& src = list[polyIdx];
-
- // generate a new unique vertex for the corresponding index - but only
- // if we can find the index in the face
- bool had = false;
- for (unsigned int i = 0; i < src.mNumIndices;++i) {
-
- unsigned int srcIdx = src.mIndices[i], tmp = idx;
- do {
- if (tmp == srcIdx)
- break;
- }
- while ((tmp = refList[tmp]) != 0xffffffff);
- if (tmp == 0xffffffff)
- continue;
-
- had = true;
- refList.resize(refList.size()+1, 0xffffffff);
-
- idx = (unsigned int)pointList.size();
- src.mIndices[i] = (unsigned int)pointList.size();
-
- // store the index of the new vertex in the old vertex
- // so we get a single linked list we can traverse in
- // only one direction
- AddToSingleLinkedList(refList,srcIdx,src.mIndices[i]);
- pointList.push_back(pointList[srcIdx]);
-
- CreateNewEntry(mCurLayer->mVColorChannels, srcIdx );
- CreateNewEntry(mCurLayer->mUVChannels, srcIdx );
- CreateNewEntry(mCurLayer->mWeightChannels, srcIdx );
- CreateNewEntry(mCurLayer->mSWeightChannels, srcIdx );
- CreateNewEntry(mCurLayer->mNormals, srcIdx );
- }
- if (!had) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', vertex index wasn't found in that polygon");
- ai_assert(had);
- }
- }
- }
- for (unsigned int l = 0; l < type;++l)
- temp[l] = GetF4();
-
- DoRecursiveVMAPAssignment(base,type,idx, temp);
- mFileBuffer += diff;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 clip
-void LWOImporter::LoadLWO2Clip(unsigned int length)
-{
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,CLIP,10);
-
- mClips.push_back(LWO::Clip());
- LWO::Clip& clip = mClips.back();
-
- // first - get the index of the clip
- clip.idx = GetU4();
-
- IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
- switch (head->type)
- {
- case AI_LWO_STIL:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,STIL,1);
-
- // "Normal" texture
- GetS0(clip.path,head->length);
- clip.type = Clip::STILL;
- break;
-
- case AI_LWO_ISEQ:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ISEQ,16);
- // Image sequence. We'll later take the first.
- {
- uint8_t digits = GetU1(); mFileBuffer++;
- int16_t offset = GetU2(); mFileBuffer+=4;
- int16_t start = GetU2(); mFileBuffer+=4;
-
- std::string s;std::stringstream ss;
- GetS0(s,head->length);
-
- head->length -= (unsigned int)s.length()+1;
- ss << s;
- ss << std::setw(digits) << offset + start;
- GetS0(s,head->length);
- ss << s;
- clip.path = ss.str();
- clip.type = Clip::SEQ;
- }
- break;
-
- case AI_LWO_STCC:
- DefaultLogger::get()->warn("LWO2: Color shifted images are not supported");
- break;
-
- case AI_LWO_ANIM:
- DefaultLogger::get()->warn("LWO2: Animated textures are not supported");
- break;
-
- case AI_LWO_XREF:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,XREF,4);
-
- // Just a cross-reference to another CLIp
- clip.type = Clip::REF;
- clip.clipRef = GetU4();
- break;
-
- case AI_LWO_NEGA:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,NEGA,2);
- clip.negate = (0 != GetU2());
- break;
-
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown CLIP subchunk");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load envelope description
-void LWOImporter::LoadLWO2Envelope(unsigned int length)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + length;
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,ENVL,4);
-
- mEnvelopes.push_back(LWO::Envelope());
- LWO::Envelope& envelope = mEnvelopes.back();
-
- // Get the index of the envelope
- envelope.index = ReadVSizedIntLWO2(mFileBuffer);
-
- // It looks like there might be an extra U4 right after the index,
- // at least in modo (LXOB) files: we'll ignore it if it's zero,
- // otherwise it represents the start of a subchunk, so we backtrack.
- if (mIsLXOB)
- {
- uint32_t extra = GetU4();
- if (extra)
- {
- mFileBuffer -= 4;
- }
- }
-
- // ... and read all subchunks
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- throw DeadlyImportError("LWO2: Invalid envelope chunk length");
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- // Type & representation of the envelope
- case AI_LWO_TYPE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TYPE,2);
- mFileBuffer++; // skip user format
-
- // Determine type of envelope
- envelope.type = (LWO::EnvelopeType)*mFileBuffer;
- ++mFileBuffer;
- break;
-
- // precondition
- case AI_LWO_PRE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,PRE,2);
- envelope.pre = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // postcondition
- case AI_LWO_POST:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,POST,2);
- envelope.post = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // keyframe
- case AI_LWO_KEY:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,KEY,8);
-
- envelope.keys.push_back(LWO::Key());
- LWO::Key& key = envelope.keys.back();
-
- key.time = GetF4();
- key.value = GetF4();
- break;
- }
-
- // interval interpolation
- case AI_LWO_SPAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPAN,4);
- if (envelope.keys.size()<2)
- DefaultLogger::get()->warn("LWO2: Unexpected SPAN chunk");
- else {
- LWO::Key& key = envelope.keys.back();
- switch (GetU4())
- {
- case AI_LWO_STEP:
- key.inter = LWO::IT_STEP;break;
- case AI_LWO_LINE:
- key.inter = LWO::IT_LINE;break;
- case AI_LWO_TCB:
- key.inter = LWO::IT_TCB;break;
- case AI_LWO_HERM:
- key.inter = LWO::IT_HERM;break;
- case AI_LWO_BEZI:
- key.inter = LWO::IT_BEZI;break;
- case AI_LWO_BEZ2:
- key.inter = LWO::IT_BEZ2;break;
- default:
- DefaultLogger::get()->warn("LWO2: Unknown interval interpolation mode");
- };
-
- // todo ... read params
- }
- break;
- }
-
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown ENVL subchunk");
- }
- // regardless how much we did actually read, go to the next chunk
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load file - master function
-void LWOImporter::LoadLWO2File()
-{
- bool skip = false;
-
- LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
- while (true)
- {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
- IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- {
- throw DeadlyImportError("LWO2: Chunk length points behind the file");
- break;
- }
- uint8_t* const next = mFileBuffer+head->length;
- unsigned int iUnnamed = 0;
-
- switch (head->type)
- {
- // new layer
- case AI_LWO_LAYR:
- {
- // add a new layer to the list ....
- mLayers->push_back ( LWO::Layer() );
- LWO::Layer& layer = mLayers->back();
- mCurLayer = &layer;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
-
- // Continue loading this layer or ignore it? Check the layer index property
- // NOTE: The first layer is the default layer, so the layer index is one-based now
- if (0xffffffff != configLayerIndex && configLayerIndex != mLayers->size()-1) {
- skip = true;
- }
- else skip = false;
-
- // layer index. that's just for internal parenting, from the scope of a LWS file
- // all layers are numbered in the oder in which they appear in the file
- layer.mIndex = GetU2();
-
- // pivot point
- mFileBuffer += 2; /* unknown */
- mCurLayer->mPivot.x = GetF4();
- mCurLayer->mPivot.y = GetF4();
- mCurLayer->mPivot.z = GetF4();
- GetS0(layer.mName,head->length-16);
-
- // if the name is empty, generate a default name
- if (layer.mName.empty()) {
- char buffer[128]; // should be sufficiently large
- ::sprintf(buffer,"Layer_%i", iUnnamed++);
- layer.mName = buffer;
- }
-
- // load this layer or ignore it? Check the layer name property
- if (configLayerName.length() && configLayerName != layer.mName) {
- skip = true;
- }
- else hasNamedLayer = true;
-
- // optional: parent of this layer
- if (mFileBuffer + 2 <= next)
- layer.mParent = GetU2();
-
- break;
- }
-
- // vertex list
- case AI_LWO_PNTS:
- {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mTempPoints.size();
- LoadLWOPoints(head->length);
- mCurLayer->mPointIDXOfs = old;
- break;
- }
- // vertex tags
- case AI_LWO_VMAD:
- if (mCurLayer->mFaces.empty())
- {
- DefaultLogger::get()->warn("LWO2: Unexpected VMAD chunk");
- break;
- }
- // --- intentionally no break here
- case AI_LWO_VMAP:
- {
- if (skip)
- break;
-
- if (mCurLayer->mTempPoints.empty())
- DefaultLogger::get()->warn("LWO2: Unexpected VMAP chunk");
- else LoadLWO2VertexMap(head->length,head->type == AI_LWO_VMAD);
- break;
- }
- // face list
- case AI_LWO_POLS:
- {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mFaces.size();
- LoadLWO2Polygons(head->length);
- mCurLayer->mFaceIDXOfs = old;
- break;
- }
- // polygon tags
- case AI_LWO_PTAG:
- {
- if (skip)
- break;
-
- if (mCurLayer->mFaces.empty())
- DefaultLogger::get()->warn("LWO2: Unexpected PTAG");
- else LoadLWO2PolygonTags(head->length);
- break;
- }
- // list of tags
- case AI_LWO_TAGS:
- {
- if (!mTags->empty())
- DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice");
- else LoadLWOTags(head->length);
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF:
- {
- LoadLWO2Surface(head->length);
- break;
- }
-
- // clip chunk
- case AI_LWO_CLIP:
- {
- LoadLWO2Clip(head->length);
- break;
- }
-
- // envelope chunk
- case AI_LWO_ENVL:
- {
- LoadLWO2Envelope(head->length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/3rdparty/assimp/code/LWOLoader.h b/3rdparty/assimp/code/LWOLoader.h
deleted file mode 100644
index 0c186d08..00000000
--- a/3rdparty/assimp/code/LWOLoader.h
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Declaration of the LWO importer class. */
-#ifndef AI_LWOLOADER_H_INCLUDED
-#define AI_LWOLOADER_H_INCLUDED
-
-#include "../include/aiTypes.h"
-#include "../include/DefaultLogger.h"
-
-#include "LWOFileData.h"
-#include "BaseImporter.h"
-#include "MaterialSystem.h"
-
-struct aiTexture;
-struct aiNode;
-
-namespace Assimp {
-using namespace LWO;
-
-// ---------------------------------------------------------------------------
-/** Class to load LWO files.
- *
- * @note Methods named "xxxLWO2[xxx]" are used with the newer LWO2 format.
- * Methods named "xxxLWOB[xxx]" are used with the older LWOB format.
- * Methods named "xxxLWO[xxx]" are used with both formats.
- * Methods named "xxx" are used to preprocess the loaded data -
- * they aren't specific to one format version
-*/
-// ---------------------------------------------------------------------------
-class LWOImporter : public BaseImporter
-{
- friend class Importer;
-
-
-protected:
- /** Constructor to be privately used by Importer */
- LWOImporter();
-
- /** Destructor, private as well */
- ~LWOImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions)
- {
- extensions.insert("lxo");
- extensions.insert("lwo");
- }
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- // -------------------------------------------------------------------
- /** Loads a LWO file in the older LWOB format (LW < 6)
- */
- void LoadLWOBFile();
-
- // -------------------------------------------------------------------
- /** Loads a LWO file in the newer LWO2 format (LW >= 6)
- */
- void LoadLWO2File();
-
-
- // -------------------------------------------------------------------
- /** Parsing functions used for all file format versions
- */
- inline void GetS0(std::string& out,unsigned int max);
- inline float GetF4();
- inline uint32_t GetU4();
- inline uint16_t GetU2();
- inline uint8_t GetU1();
-
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWOB file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOBSurface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWO2 file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWO2Surface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a texture block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head,
- unsigned int size );
-
- // -------------------------------------------------------------------
- /** Loads a shader block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head,
- unsigned int size );
-
- // -------------------------------------------------------------------
- /** Loads an image map from a LWO2 file
- * @param size Maximum size to be read, in bytes.
- * @param tex Texture object to be filled
- */
- void LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex );
- void LoadLWO2Gradient(unsigned int size, LWO::Texture& tex );
- void LoadLWO2Procedural(unsigned int size, LWO::Texture& tex );
-
- // loads the header - used by thethree functions above
- void LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex );
-
- // -------------------------------------------------------------------
- /** Loads the LWO tag list from the file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOTags(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Load polygons from a POLS chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Polygons(unsigned int length);
- void LoadLWOBPolygons(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load polygon tags from a PTAG chunk
- * @param length Size of the chunk
- */
- void LoadLWO2PolygonTags(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a vertex map from a VMAP/VMAD chunk
- * @param length Size of the chunk
- * @param perPoly Operate on per-polygon base?
- */
- void LoadLWO2VertexMap(unsigned int length, bool perPoly);
-
- // -------------------------------------------------------------------
- /** Load polygons from a PNTS chunk
- * @param length Size of the chunk
- */
- void LoadLWOPoints(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a clip from a CLIP chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Clip(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load an envelope from an EVL chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Envelope(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Count vertices and faces in a LWOB/LWO2 file
- */
- void CountVertsAndFacesLWO2(unsigned int& verts,
- unsigned int& faces,
- uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = 0xffffffff);
-
- void CountVertsAndFacesLWOB(unsigned int& verts,
- unsigned int& faces,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = 0xffffffff);
-
- // -------------------------------------------------------------------
- /** Read vertices and faces in a LWOB/LWO2 file
- */
- void CopyFaceIndicesLWO2(LWO::FaceList::iterator& it,
- uint16_t*& cursor,
- const uint16_t* const end);
-
- // -------------------------------------------------------------------
- void CopyFaceIndicesLWOB(LWO::FaceList::iterator& it,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = 0xffffffff);
-
- // -------------------------------------------------------------------
- /** Resolve the tag and surface lists that have been loaded.
- * Generates the mMapping table.
- */
- void ResolveTags();
-
- // -------------------------------------------------------------------
- /** Resolve the clip list that has been loaded.
- * Replaces clip references with real clips.
- */
- void ResolveClips();
-
- // -------------------------------------------------------------------
- /** Add a texture list to an output material description.
- *
- * @param pcMat Output material
- * @param in Input texture list
- * @param type Type identifier of the texture list
- */
- bool HandleTextures(MaterialHelper* pcMat, const TextureList& in,
- aiTextureType type);
-
- // -------------------------------------------------------------------
- /** Adjust a texture path
- */
- void AdjustTexturePath(std::string& out);
-
- // -------------------------------------------------------------------
- /** Convert a LWO surface description to an ASSIMP material
- */
- void ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat);
-
-
- // -------------------------------------------------------------------
- /** Get a list of all UV/VC channels required by a specific surface.
- *
- * @param surf Working surface
- * @param layer Working layer
- * @param out Output list. The members are indices into the
- * UV/VC channel lists of the layer
- */
- void FindUVChannels(/*const*/ LWO::Surface& surf,
- LWO::SortedRep& sorted,
- /*const*/ LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]);
-
- // -------------------------------------------------------------------
- char FindUVChannels(LWO::TextureList& list,
- LWO::Layer& layer,LWO::UVChannel& uv, unsigned int next);
-
- // -------------------------------------------------------------------
- void FindVCChannels(const LWO::Surface& surf,
- LWO::SortedRep& sorted,
- const LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]);
-
- // -------------------------------------------------------------------
- /** Generate the final node graph
- * Unused nodes are deleted.
- * @param apcNodes Flat list of nodes
- */
- void GenerateNodeGraph(std::vector<aiNode*>& apcNodes);
-
- // -------------------------------------------------------------------
- /** Add children to a node
- * @param node Node to become a father
- * @param parent Index of the node
- * @param apcNodes Flat list of nodes - used nodes are set to NULL.
- */
- void AddChildren(aiNode* node, uint16_t parent,
- std::vector<aiNode*>& apcNodes);
-
- // -------------------------------------------------------------------
- /** Read a variable sized integer
- * @param inout Input and output buffer
- */
- int ReadVSizedIntLWO2(uint8_t*& inout);
-
- // -------------------------------------------------------------------
- /** Assign a value from a VMAP to a vertex and all vertices
- * attached to it.
- * @param base VMAP destination data
- * @param numRead Number of float's to be read
- * @param idx Absolute index of the first vertex
- * @param data Value of the VMAP to be assigned - read numRead
- * floats from this array.
- */
- void DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead,
- unsigned int idx, float* data);
-
- // -------------------------------------------------------------------
- /** Compute normal vectors for a mesh
- * @param mesh Input mesh
- * @param smoothingGroups Smoothing-groups-per-face array
- * @param surface Surface for the mesh
- */
- void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
- const LWO::Surface& surface);
-
-
- // -------------------------------------------------------------------
- /** Setup a new texture after the corresponding chunk was
- * encountered in the file.
- * @param list Texture list
- * @param size Maximum number of bytes to be read
- * @return Pointer to new texture
- */
- LWO::Texture* SetupNewTextureLWOB(LWO::TextureList& list,
- unsigned int size);
-
-protected:
-
- /** true if the file is a LWO2 file*/
- bool mIsLWO2;
-
- /** true if the file is a LXOB file*/
- bool mIsLXOB;
-
- /** Temporary list of layers from the file */
- LayerList* mLayers;
-
- /** Pointer to the current layer */
- LWO::Layer* mCurLayer;
-
- /** Temporary tag list from the file */
- TagList* mTags;
-
- /** Mapping table to convert from tag to surface indices.
- 0xffffffff indicates that a no corresponding surface is available */
- TagMappingTable* mMapping;
-
- /** Temporary surface list from the file */
- SurfaceList* mSurfaces;
-
- /** Temporary clip list from the file */
- ClipList mClips;
-
- /** Temporary envelope list from the file */
- EnvelopeList mEnvelopes;
-
- /** file buffer */
- uint8_t* mFileBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Output scene */
- aiScene* pScene;
-
- /** Configuration option: speed flag set? */
- bool configSpeedFlag;
-
- /** Configuration option: index of layer to be loaded */
- unsigned int configLayerIndex;
-
- /** Configuration option: name of layer to be loaded */
- std::string configLayerName;
-
- /** True if we have a named layer */
- bool hasNamedLayer;
-};
-
-
-// ------------------------------------------------------------------------------------------------
-inline float LWOImporter::GetF4()
-{
- float f = *((float*)mFileBuffer);mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint32_t LWOImporter::GetU4()
-{
- uint32_t f = *((uint32_t*)mFileBuffer);mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint16_t LWOImporter::GetU2()
-{
- uint16_t f = *((uint16_t*)mFileBuffer);mFileBuffer += 2;
- AI_LSWAP2(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint8_t LWOImporter::GetU1()
-{
- return *mFileBuffer++;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline int LWOImporter::ReadVSizedIntLWO2(uint8_t*& inout)
-{
- int i;
- int c = *inout;inout++;
- if (c != 0xFF)
- {
- i = c << 8;
- c = *inout;inout++;
- i |= c;
- }
- else
- {
- c = *inout;inout++;
- i = c << 16;
- c = *inout;inout++;
- i |= c << 8;
- c = *inout;inout++;
- i |= c;
- }
- return i;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::GetS0(std::string& out,unsigned int max)
-{
- unsigned int iCursor = 0;
- const char*sz = (const char*)mFileBuffer;
- while (*mFileBuffer)
- {
- if (++iCursor > max)
- {
- DefaultLogger::get()->warn("LWO: Invalid file, string is is too long");
- break;
- }
- ++mFileBuffer;
- }
- size_t len = (size_t) ((const char*)mFileBuffer-sz);
- out = std::string(sz,len);
- mFileBuffer += (len&0x1 ? 1 : 2);
-}
-
-
-
-} // end of namespace Assimp
-
-#endif // AI_LWOIMPORTER_H_INCLUDED
diff --git a/3rdparty/assimp/code/LWOMaterial.cpp b/3rdparty/assimp/code/LWOMaterial.cpp
deleted file mode 100644
index 8af631af..00000000
--- a/3rdparty/assimp/code/LWOMaterial.cpp
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the material oart of the LWO importer class */
-
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "LWOLoader.h"
-#include "MaterialSystem.h"
-#include "ByteSwap.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-T lerp(const T& one, const T& two, float val)
-{
- return one + (two-one)*val;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a lightwave mapping mode to our's
-inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
-{
- switch (in)
- {
- case LWO::Texture::REPEAT:
- return aiTextureMapMode_Wrap;
-
- case LWO::Texture::MIRROR:
- return aiTextureMapMode_Mirror;
-
- case LWO::Texture::RESET:
- DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
-
- // fall though here
- case LWO::Texture::EDGE:
- return aiTextureMapMode_Clamp;
- }
- return (aiTextureMapMode)0;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, aiTextureType type)
-{
- ai_assert(NULL != pcMat);
-
- unsigned int cur = 0, temp = 0;
- aiString s;
- bool ret = false;
-
- for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it) {
- if (!(*it).enabled || !(*it).bCanUse)
- continue;
- ret = true;
-
- // Convert lightwave's mapping modes to ours. We let them
- // as they are, the GenUVcoords step will compute UV
- // channels if they're not there.
-
- aiTextureMapping mapping;
- switch ((*it).mapMode)
- {
- case LWO::Texture::Planar:
- mapping = aiTextureMapping_PLANE;
- break;
- case LWO::Texture::Cylindrical:
- mapping = aiTextureMapping_CYLINDER;
- break;
- case LWO::Texture::Spherical:
- mapping = aiTextureMapping_SPHERE;
- break;
- case LWO::Texture::Cubic:
- mapping = aiTextureMapping_BOX;
- break;
- case LWO::Texture::FrontProjection:
- DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
- mapping = aiTextureMapping_OTHER;
- break;
- case LWO::Texture::UV:
- {
- if ( 0xffffffff == (*it).mRealUVIndex ) {
- // We have no UV index for this texture, so we can't display it
- continue;
- }
-
- // add the UV source index
- temp = (*it).mRealUVIndex;
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));
-
- mapping = aiTextureMapping_UV;
- }
- break;
- default:
- ai_assert(false);
- };
-
- if (mapping != aiTextureMapping_UV) {
- // Setup the main axis
- aiVector3D v;
- switch ((*it).majorAxis) {
- case Texture::AXIS_X:
- v = aiVector3D(1.f,0.f,0.f);
- break;
- case Texture::AXIS_Y:
- v = aiVector3D(0.f,1.f,0.f);
- break;
- default: // case Texture::AXIS_Z:
- v = aiVector3D(0.f,0.f,1.f);
- break;
- }
-
- pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
-
- // Setup UV scalings for cylindric and spherical projections
- if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) {
- aiUVTransform trafo;
- trafo.mScaling.x = (*it).wrapAmountW;
- trafo.mScaling.y = (*it).wrapAmountH;
-
- BOOST_STATIC_ASSERT(sizeof(aiUVTransform)/sizeof(float) == 5);
- pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
- }
- DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
- }
-
- // The older LWOB format does not use indirect references to clips.
- // The file name of a texture is directly specified in the tex chunk.
- if (mIsLWO2) {
- // find the corresponding clip
- ClipList::iterator clip = mClips.begin();
- temp = (*it).mClipIdx;
- for (ClipList::iterator end = mClips.end(); clip != end; ++clip) {
- if ((*clip).idx == temp)
- break;
-
- }
- if (mClips.end() == clip) {
- DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
- temp = 0;
-
- // fixme: appearently some LWO files shipping with Doom3 don't
- // have clips at all ... check whether that's true or whether
- // it's a bug in the loader.
-
- s.Set("$texture.png");
-
- //continue;
- }
- else {
- if (Clip::UNSUPPORTED == (*clip).type) {
- DefaultLogger::get()->error("LWO2: Clip type is not supported");
- continue;
- }
- AdjustTexturePath((*clip).path);
- s.Set((*clip).path);
-
- // Additional image settings
- int flags = 0;
- if ((*clip).negate) {
- flags |= aiTextureFlags_Invert;
- }
- pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
- }
- }
- else
- {
- std::string ss = (*it).mFileName;
- if (!ss.length()) {
- DefaultLogger::get()->error("LWOB: Empty file name");
- continue;
- }
- AdjustTexturePath(ss);
- s.Set(ss);
- }
- pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));
-
- // add the blend factor
- pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur));
-
- // add the blend operation
- switch ((*it).blendType)
- {
- case LWO::Texture::Normal:
- case LWO::Texture::Multiply:
- temp = (unsigned int)aiTextureOp_Multiply;
- break;
-
- case LWO::Texture::Subtractive:
- case LWO::Texture::Difference:
- temp = (unsigned int)aiTextureOp_Subtract;
- break;
-
- case LWO::Texture::Divide:
- temp = (unsigned int)aiTextureOp_Divide;
- break;
-
- case LWO::Texture::Additive:
- temp = (unsigned int)aiTextureOp_Add;
- break;
-
- default:
- temp = (unsigned int)aiTextureOp_Multiply;
- DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");
-
- }
- // Setup texture operation
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
-
- // setup the mapping mode
- pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
-
- // add the u-wrapping
- temp = (unsigned int)GetMapMode((*it).wrapModeWidth);
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));
-
- // add the v-wrapping
- temp = (unsigned int)GetMapMode((*it).wrapModeHeight);
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));
-
- ++cur;
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat)
-{
- // copy the name of the surface
- aiString st;
- st.Set(surf.mName);
- pcMat->AddProperty(&st,AI_MATKEY_NAME);
-
- const int i = surf.bDoubleSided ? 1 : 0;
- pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
-
- // add the refraction index and the bump intensity
- pcMat->AddProperty(&surf.mIOR,1,AI_MATKEY_REFRACTI);
- pcMat->AddProperty(&surf.mBumpIntensity,1,AI_MATKEY_BUMPSCALING);
-
- aiShadingMode m;
- if (surf.mSpecularValue && surf.mGlossiness)
- {
- float fGloss;
- if (mIsLWO2) {
- fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
- }
- else
- {
- if (16.0f >= surf.mGlossiness)
- fGloss = 6.0f;
- else if (64.0f >= surf.mGlossiness)
- fGloss = 20.0f;
- else if (256.0f >= surf.mGlossiness)
- fGloss = 50.0f;
- else fGloss = 80.0f;
- }
-
- pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
- pcMat->AddProperty(&fGloss,1,AI_MATKEY_SHININESS);
- m = aiShadingMode_Phong;
- }
- else m = aiShadingMode_Gouraud;
-
- // specular color
- aiColor3D clr = lerp( aiColor3D(1.f,1.f,1.f), surf.mColor, surf.mColorHighlights );
- pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
- pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
-
- // emissive color
- // luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
- clr.g = clr.b = clr.r = surf.mLuminosity*0.8f;
- pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
-
- // opacity ... either additive or default-blended, please
- if (0.f != surf.mAdditiveTransparency) {
-
- const int add = aiBlendMode_Additive;
- pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
- pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC);
- }
-
- else if (10e10f != surf.mTransparency) {
- const int def = aiBlendMode_Default;
- const float f = 1.0f-surf.mTransparency;
- pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY);
- pcMat->AddProperty(&def,1,AI_MATKEY_BLEND_FUNC);
- }
-
-
- // ADD TEXTURES to the material
- // TODO: find out how we can handle COLOR textures correctly...
- bool b = HandleTextures(pcMat,surf.mColorTextures,aiTextureType_DIFFUSE);
- b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,aiTextureType_DIFFUSE));
- HandleTextures(pcMat,surf.mSpecularTextures,aiTextureType_SPECULAR);
- HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS);
- HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT);
- HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY);
- HandleTextures(pcMat,surf.mReflectionTextures,aiTextureType_REFLECTION);
-
- // Now we need to know which shader to use .. iterate through the shader list of
- // the surface and search for a name which we know ...
- for (ShaderList::const_iterator it = surf.mShaders.begin(), end = surf.mShaders.end();it != end;++it) {
- //if (!(*it).enabled)continue;
-
- if ((*it).functionName == "LW_SuperCelShader" || (*it).functionName == "AH_CelShader") {
- DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
-
- m = aiShadingMode_Toon;
- break;
- }
- else if ((*it).functionName == "LW_RealFresnel" || (*it).functionName == "LW_FastFresnel") {
- DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
-
- m = aiShadingMode_Fresnel;
- break;
- }
- else
- {
- DefaultLogger::get()->warn("LWO2: Unknown surface shader: " + (*it).functionName);
- }
- }
- if (surf.mMaximumSmoothAngle <= 0.0f)
- m = aiShadingMode_Flat;
- pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
-
- // (the diffuse value is just a scaling factor)
- // If a diffuse texture is set, we set this value to 1.0
- clr = (b && false ? aiColor3D(1.f,1.f,1.f) : surf.mColor);
- clr.r *= surf.mDiffuseValue;
- clr.g *= surf.mDiffuseValue;
- clr.b *= surf.mDiffuseValue;
- pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-}
-
-// ------------------------------------------------------------------------------------------------
-char LWOImporter::FindUVChannels(LWO::TextureList& list,
- LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
-{
- char ret = 0;
- for (TextureList::iterator it = list.begin(), end = list.end();it != end;++it) {
-
- // Ignore textures with non-UV mappings for the moment.
- if (!(*it).enabled || !(*it).bCanUse || (*it).mapMode != LWO::Texture::UV) {
- continue;
- }
-
- if ((*it).mUVChannelIndex == uv.name) {
- ret = 1;
-
- // got it.
- if ((*it).mRealUVIndex == 0xffffffff || (*it).mRealUVIndex == next)
- {
- (*it).mRealUVIndex = next;
- }
- else {
- // channel mismatch. need to duplicate the material.
- DefaultLogger::get()->warn("LWO: Channel mismatch, would need to duplicate surface [design bug]");
-
- // TODO
- }
- }
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindUVChannels(LWO::Surface& surf,
- LWO::SortedRep& sorted,LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
-{
- unsigned int next = 0, extra = 0, num_extra = 0;
-
- // Check whether we have an UV entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mUVChannels.size();++i) {
- LWO::UVChannel& uv = layer.mUVChannels[i];
-
- for (LWO::SortedRep::const_iterator it = sorted.begin(); it != sorted.end(); ++it) {
-
- LWO::Face& face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (uv.abAssigned[idx] && ((aiVector2D*)&uv.rawData[0])[idx] != aiVector2D()) {
-
- if (next >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-
- DefaultLogger::get()->error("LWO: Maximum number of UV channels for "
- "this mesh reached. Skipping channel \'" + uv.name + "\'");
-
- }
- else {
- // Search through all textures assigned to 'surf' and look for this UV channel
- char had = 0;
- had |= FindUVChannels(surf.mColorTextures,layer,uv,next);
- had |= FindUVChannels(surf.mDiffuseTextures,layer,uv,next);
- had |= FindUVChannels(surf.mSpecularTextures,layer,uv,next);
- had |= FindUVChannels(surf.mGlossinessTextures,layer,uv,next);
- had |= FindUVChannels(surf.mOpacityTextures,layer,uv,next);
- had |= FindUVChannels(surf.mBumpTextures,layer,uv,next);
- had |= FindUVChannels(surf.mReflectionTextures,layer,uv,next);
-
- if (had != 0) {
-
- // We have a texture referencing this UV channel so we have to take special care of it
- if (num_extra) {
-
- for (unsigned int a = next; a < std::min( extra, AI_MAX_NUMBER_OF_TEXTURECOORDS-1u ); ++a) {
- out[a+1] = out[a];
- }
- }
- ++extra;
- out[next++] = i;
- }
- else {
-
- // Bh ... seems not to be used at all. Push to end if enough space is available.
- out[extra++] = i;
- ++num_extra;
- }
- }
- it = sorted.end()-1;
- break;
- }
- }
- }
- }
- if (next != AI_MAX_NUMBER_OF_TEXTURECOORDS) {
- out[extra] = 0xffffffff;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorted, const LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
-{
- unsigned int next = 0;
-
- // Check whether we have an vc entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mVColorChannels.size();++i) {
- const LWO::VColorChannel& vc = layer.mVColorChannels[i];
-
- if (surf.mVCMap == vc.name) {
- // The vertex color map is explicitely requested by the surface so we need to take special care of it
- for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
- out[a+1] = out[a];
- }
- out[0] = i;
- ++next;
- }
- else {
-
- for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
- const LWO::Face& face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.f,0.f,0.f,1.f)) {
- if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
-
- DefaultLogger::get()->error("LWO: Maximum number of vertex color channels for "
- "this mesh reached. Skipping channel \'" + vc.name + "\'");
-
- }
- else {
- out[next++] = i;
- }
- it = sorted.end()-1;
- break;
- }
- }
- }
- }
- }
- if (next != AI_MAX_NUMBER_OF_COLOR_SETS) {
- out[next] = 0xffffffff;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- case AI_LWO_PROJ:
- tex.mapMode = (Texture::MappingMode)GetU2();
- break;
- case AI_LWO_WRAP:
- tex.wrapModeWidth = (Texture::Wrap)GetU2();
- tex.wrapModeHeight = (Texture::Wrap)GetU2();
- break;
- case AI_LWO_AXIS:
- tex.majorAxis = (Texture::Axes)GetU2();
- break;
- case AI_LWO_IMAG:
- tex.mClipIdx = GetU2();
- break;
- case AI_LWO_VMAP:
- GetS0(tex.mUVChannelIndex,head->length);
- break;
- case AI_LWO_WRPH:
- tex.wrapAmountH = GetF4();
- break;
- case AI_LWO_WRPW:
- tex.wrapAmountW = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
-{
- // --- not supported at the moment
- DefaultLogger::get()->error("LWO2: Found procedural texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
-{
- // --- not supported at the moment
- DefaultLogger::get()->error("LWO2: Found gradient texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- // get the ordinal string
- GetS0( tex.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!tex.ordinal.length())
- {
- DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
- tex.ordinal = "\x00";
- }
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- throw DeadlyImportError("LWO2: Invalid texture header chunk length");
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- case AI_LWO_CHAN:
- tex.type = GetU4();
- break;
- case AI_LWO_ENAB:
- tex.enabled = GetU2() ? true : false;
- break;
- case AI_LWO_OPAC:
- tex.blendType = (Texture::BlendType)GetU2();
- tex.mStrength = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
-{
- ai_assert(!mSurfaces->empty());
- LWO::Surface& surf = mSurfaces->back();
- LWO::Texture tex;
-
- // load the texture header
- LoadLWO2TextureHeader(head->length,tex);
- size -= head->length + 6;
-
- // now get the exact type of the texture
- switch (head->type)
- {
- case AI_LWO_PROC:
- LoadLWO2Procedural(size,tex);
- break;
- case AI_LWO_GRAD:
- LoadLWO2Gradient(size,tex);
- break;
- case AI_LWO_IMAP:
- LoadLWO2ImageMap(size,tex);
- }
-
- // get the destination channel
- TextureList* listRef = NULL;
- switch (tex.type)
- {
- case AI_LWO_COLR:
- listRef = &surf.mColorTextures;break;
- case AI_LWO_DIFF:
- listRef = &surf.mDiffuseTextures;break;
- case AI_LWO_SPEC:
- listRef = &surf.mSpecularTextures;break;
- case AI_LWO_GLOS:
- listRef = &surf.mGlossinessTextures;break;
- case AI_LWO_BUMP:
- listRef = &surf.mBumpTextures;break;
- case AI_LWO_TRAN:
- listRef = &surf.mOpacityTextures;break;
- case AI_LWO_REFL:
- listRef = &surf.mReflectionTextures;break;
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown texture type");
- return;
- }
-
- // now attach the texture to the parent surface - sort by ordinal string
- for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it) {
- if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
- listRef->insert(it,tex);
- return;
- }
- }
- listRef->push_back(tex);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- ai_assert(!mSurfaces->empty());
- LWO::Surface& surf = mSurfaces->back();
- LWO::Shader shader;
-
- // get the ordinal string
- GetS0( shader.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!shader.ordinal.length())
- {
- DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
- shader.ordinal = "\x00";
- }
-
- // read the header
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- throw DeadlyImportError("LWO2: Invalid shader header chunk length");
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- case AI_LWO_ENAB:
- shader.enabled = GetU2() ? true : false;
- break;
-
- case AI_LWO_FUNC:
- GetS0( shader.functionName, head->length );
- }
- mFileBuffer = next;
- }
-
- // now attach the shader to the parent surface - sort by ordinal string
- for (ShaderList::iterator it = surf.mShaders.begin();it != surf.mShaders.end(); ++it) {
- if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
- surf.mShaders.insert(it,shader);
- return;
- }
- }
- surf.mShaders.push_back(shader);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Surface(unsigned int size)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- mSurfaces->push_back( LWO::Surface () );
- LWO::Surface& surf = mSurfaces->back();
-
- GetS0(surf.mName,size);
-
- // check whether this surface was derived from any other surface
- std::string derived;
- GetS0(derived,(unsigned int)(end - mFileBuffer));
- if (derived.length()) {
- // yes, find this surface
- for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
- if ((*it).mName == derived) {
- // we have it ...
- surf = *it;
- derived.clear();break;
- }
- }
- if (derived.size())
- DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
- }
-
- while (true)
- {
- if (mFileBuffer + 6 >= end)
- break;
- LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head->length > end)
- throw DeadlyImportError("LWO2: Invalid surface chunk length");
-
- uint8_t* const next = mFileBuffer+head->length;
- switch (head->type)
- {
- // diffuse color
- case AI_LWO_COLR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,12);
- surf.mColor.r = GetF4();
- surf.mColor.g = GetF4();
- surf.mColor.b = GetF4();
- break;
- }
- // diffuse strength ... hopefully
- case AI_LWO_DIFF:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,4);
- surf.mDiffuseValue = GetF4();
- break;
- }
- // specular strength ... hopefully
- case AI_LWO_SPEC:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,4);
- surf.mSpecularValue = GetF4();
- break;
- }
- // transparency
- case AI_LWO_TRAN:
- {
- // transparency explicitly disabled?
- if (surf.mTransparency == 10e10f)
- break;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,4);
- surf.mTransparency = GetF4();
- break;
- }
- // additive transparency
- case AI_LWO_ADTR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ADTR,4);
- surf.mAdditiveTransparency = GetF4();
- break;
- }
- // wireframe mode
- case AI_LWO_LINE:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LINE,2);
- if (GetU2() & 0x1)
- surf.mWireframe = true;
- break;
- }
- // glossiness
- case AI_LWO_GLOS:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,4);
- surf.mGlossiness = GetF4();
- break;
- }
- // bump intensity
- case AI_LWO_BUMP:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BUMP,4);
- surf.mBumpIntensity = GetF4();
- break;
- }
- // color highlights
- case AI_LWO_CLRH:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,CLRH,4);
- surf.mColorHighlights = GetF4();
- break;
- }
- // index of refraction
- case AI_LWO_RIND:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,RIND,4);
- surf.mIOR = GetF4();
- break;
- }
- // polygon sidedness
- case AI_LWO_SIDE:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SIDE,2);
- surf.bDoubleSided = (3 == GetU2());
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
- surf.mMaximumSmoothAngle = fabs( GetF4() );
- break;
- }
- // vertex color channel to be applied to the surface
- case AI_LWO_VCOL:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,VCOL,12);
- surf.mDiffuseValue *= GetF4(); // strength
- ReadVSizedIntLWO2(mFileBuffer); // skip envelope
- surf.mVCMapType = GetU4(); // type of the channel
-
- // name of the channel
- GetS0(surf.mVCMap, (unsigned int) (next - mFileBuffer ));
- break;
- }
- // surface bock entry
- case AI_LWO_BLOK:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BLOK,4);
- LE_NCONST IFF::SubChunkHeader* head2 = IFF::LoadSubChunk(mFileBuffer);
-
- switch (head2->type)
- {
- case AI_LWO_PROC:
- case AI_LWO_GRAD:
- case AI_LWO_IMAP:
- LoadLWO2TextureBlock(head2, head->length);
- break;
- case AI_LWO_SHDR:
- LoadLWO2ShaderBlock(head2, head->length);
- break;
-
- default:
- DefaultLogger::get()->warn("LWO2: Found an unsupported surface BLOK");
- };
-
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
diff --git a/3rdparty/assimp/code/LWSLoader.cpp b/3rdparty/assimp/code/LWSLoader.cpp
deleted file mode 100644
index d0034b8c..00000000
--- a/3rdparty/assimp/code/LWSLoader.cpp
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file LWSLoader.cpp
- * @brief Implementation of the LWS importer class
- */
-
-#include "AssimpPCH.h"
-
-#include "LWSLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include "SceneCombiner.h"
-#include "GenericProperty.h"
-#include "SkeletonMeshBuilder.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Recursive parsing of LWS files
-void LWS::Element::Parse (const char*& buffer)
-{
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
-
- // begin of a new element with children
- bool sub = false;
- if (*buffer == '{') {
- ++buffer;
- SkipSpaces(&buffer);
- sub = true;
- }
- else if (*buffer == '}')
- return;
-
- children.push_back(Element());
-
- // copy data line - read token per token
-
- const char* cur = buffer;
- while (!IsSpaceOrNewLine(*buffer)) ++buffer;
- children.back().tokens[0] = std::string(cur,(size_t) (buffer-cur));
- SkipSpaces(&buffer);
-
- if (children.back().tokens[0] == "Plugin")
- {
- DefaultLogger::get()->debug("LWS: Skipping over plugin-specific data");
-
- // strange stuff inside Plugin/Endplugin blocks. Needn't
- // follow LWS syntax, so we skip over it
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
- if (!::strncmp(buffer,"EndPlugin",9)) {
- //SkipLine(&buffer);
- break;
- }
- }
- continue;
- }
-
- cur = buffer;
- while (!IsLineEnd(*buffer)) ++buffer;
- children.back().tokens[1] = std::string(cur,(size_t) (buffer-cur));
-
- // parse more elements recursively
- if (sub)
- children.back().Parse(buffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LWSImporter::LWSImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LWSImporter::~LWSImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "lws" || extension == "mot")
- return true;
-
- // if check for extension is not enough, check for the magic tokens LWSC and LWMO
- if (!extension.length() || checkSig) {
- uint32_t tokens[2];
- tokens[0] = AI_MAKE_MAGIC("LWSC");
- tokens[1] = AI_MAKE_MAGIC("LWMO");
- return CheckMagicToken(pIOHandler,pFile,tokens,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of file extensions
-void LWSImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("lws");
- extensions.insert("mot");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void LWSImporter::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-
- // AI_CONFIG_IMPORT_LWS_ANIM_START
- first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
- 150392 /* magic hack */);
-
- // AI_CONFIG_IMPORT_LWS_ANIM_END
- last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
- 150392 /* magic hack */);
-
- if (last < first) {
- std::swap(last,first);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read an envelope description
-void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
-{
- if (dad.children.empty()) {
- DefaultLogger::get()->error("LWS: Envelope descriptions must not be empty");
- return;
- }
-
- // reserve enough storage
- std::list< LWS::Element >::const_iterator it = dad.children.begin();;
- fill.keys.reserve(strtol10(it->tokens[1].c_str()));
-
- for (++it; it != dad.children.end(); ++it) {
- const char* c = (*it).tokens[1].c_str();
-
- if ((*it).tokens[0] == "Key") {
- fill.keys.push_back(LWO::Key());
- LWO::Key& key = fill.keys.back();
-
- float f;
- SkipSpaces(&c);
- c = fast_atof_move(c,key.value);
- SkipSpaces(&c);
- c = fast_atof_move(c,f);
-
- key.time = f;
-
- unsigned int span = strtol10(c,&c), num = 0;
- switch (span) {
-
- case 0:
- key.inter = LWO::IT_TCB;
- num = 5;
- break;
- case 1:
- case 2:
- key.inter = LWO::IT_HERM;
- num = 5;
- break;
- case 3:
- key.inter = LWO::IT_LINE;
- num = 0;
- break;
- case 4:
- key.inter = LWO::IT_STEP;
- num = 0;
- break;
- case 5:
- key.inter = LWO::IT_BEZ2;
- num = 4;
- break;
- default:
- DefaultLogger::get()->error("LWS: Unknown span type");
- }
- for (unsigned int i = 0; i < num;++i) {
- SkipSpaces(&c);
- c = fast_atof_move(c,key.params[i]);
- }
- }
- else if ((*it).tokens[0] == "Behaviors") {
- SkipSpaces(&c);
- fill.pre = (LWO::PrePostBehaviour) strtol10(c,&c);
- SkipSpaces(&c);
- fill.post = (LWO::PrePostBehaviour) strtol10(c,&c);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read animation channels in the old LightWave animation format
-void LWSImporter::ReadEnvelope_Old(
- std::list< LWS::Element >::const_iterator& it,
- const std::list< LWS::Element >::const_iterator& end,
- LWS::NodeDesc& nodes,
- unsigned int /*version*/)
-{
- unsigned int num,sub_num;
- if (++it == end)goto unexpected_end;
-
- num = strtol10((*it).tokens[0].c_str());
- for (unsigned int i = 0; i < num; ++i) {
-
- nodes.channels.push_back(LWO::Envelope());
- LWO::Envelope& envl = nodes.channels.back();
-
- envl.index = i;
- envl.type = (LWO::EnvelopeType)(i+1);
-
- if (++it == end)goto unexpected_end;
- sub_num = strtol10((*it).tokens[0].c_str());
-
- for (unsigned int n = 0; n < sub_num;++n) {
-
- if (++it == end)goto unexpected_end;
-
- // parse value and time, skip the rest for the moment.
- LWO::Key key;
- const char* c = fast_atof_move((*it).tokens[0].c_str(),key.value);
- SkipSpaces(&c);
- float f;
- fast_atof_move((*it).tokens[0].c_str(),f);
- key.time = f;
-
- envl.keys.push_back(key);
- }
- }
- return;
-
-unexpected_end:
- DefaultLogger::get()->error("LWS: Encountered unexpected end of file while parsing object motion");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup a nice name for a node
-void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
-{
- const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
-
- // the name depends on the type. We break LWS's strange naming convention
- // and return human-readable, but still machine-parsable and unique, strings.
- if (src.type == LWS::NodeDesc::OBJECT) {
-
- if (src.path.length()) {
- std::string::size_type s = src.path.find_last_of("\\/");
- if (s == std::string::npos)
- s = 0;
- else ++s;
-
- nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.path.substr(s).c_str(),combined);
- return;
- }
- }
- nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.name,combined);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively build the scenegraph
-void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach,
- BatchLoader& batch,
- aiCamera**& camOut,
- aiLight**& lightOut,
- std::vector<aiNodeAnim*>& animOut)
-{
- // Setup a very cryptic name for the node, we want the user to be happy
- SetupNodeName(nd,src);
-
- // If this is an object from an external file - get the scene and setup proper attachment tags
- aiScene* obj = NULL;
- if (src.type == LWS::NodeDesc::OBJECT && src.path.length() ) {
- obj = batch.GetImport(src.id);
- if (!obj) {
- DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
- }
- else {
- attach.push_back(AttachmentInfo(obj,nd));
- }
- }
-
- // If object is a light source - setup a corresponding ai structure
- else if (src.type == LWS::NodeDesc::LIGHT) {
- aiLight* lit = *lightOut++ = new aiLight();
-
- // compute final light color
- lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity;
-
- // name to attach light to node -> unique due to LWs indexing system
- lit->mName = nd->mName;
-
- // detemine light type and setup additional members
- if (src.lightType == 2) { /* spot light */
-
- lit->mType = aiLightSource_SPOT;
- lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle );
- lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle );
-
- }
- else if (src.lightType == 1) { /* directional light source */
- lit->mType = aiLightSource_DIRECTIONAL;
- }
- else lit->mType = aiLightSource_POINT;
-
- // fixme: no proper handling of light falloffs yet
- if (src.lightFalloffType == 1)
- lit->mAttenuationConstant = 1.f;
- else if (src.lightFalloffType == 1)
- lit->mAttenuationLinear = 1.f;
- else
- lit->mAttenuationQuadratic = 1.f;
- }
-
- // If object is a camera - setup a corresponding ai structure
- else if (src.type == LWS::NodeDesc::CAMERA) {
- aiCamera* cam = *camOut++ = new aiCamera();
-
- // name to attach cam to node -> unique due to LWs indexing system
- cam->mName = nd->mName;
- }
-
- // Get the node transformation from the LWO key
- LWO::AnimResolver resolver(src.channels,fps);
- resolver.ExtractBindPose(nd->mTransformation);
-
- // .. and construct animation channels
- aiNodeAnim* anim = NULL;
-
- if (first != last) {
- resolver.SetAnimationRange(first,last);
- resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
- if (anim) {
- anim->mNodeName = nd->mName;
- animOut.push_back(anim);
- }
- }
-
- // process pivot point, if any
- if (src.pivotPos != aiVector3D()) {
- aiMatrix4x4 tmp;
- aiMatrix4x4::Translation(-src.pivotPos,tmp);
-
- if (anim) {
-
- // We have an animation channel for this node. Problem: to combine the pivot
- // point with the node anims, we'd need to interpolate *all* keys, get
- // transformation matrices from them, apply the translation and decompose
- // the resulting matrices again in order to reconstruct the keys. This
- // solution here is *much* easier ... we're just inserting an extra node
- // in the hierarchy.
- // Maybe the final optimization here will be done during postprocessing.
-
- aiNode* pivot = new aiNode();
- pivot->mName.length = sprintf( pivot->mName.data, "$Pivot_%s",nd->mName.data);
- pivot->mTransformation = tmp;
-
- pivot->mChildren = new aiNode*[pivot->mNumChildren = 1];
- pivot->mChildren[0] = nd;
-
- pivot->mParent = nd->mParent;
- nd->mParent = pivot;
-
- // swap children and hope the parents wont see a huge difference
- pivot->mParent->mChildren[pivot->mParent->mNumChildren-1] = pivot;
- }
- else {
- nd->mTransformation = tmp*nd->mTransformation;
- }
- }
-
- // Add children
- if (src.children.size()) {
- nd->mChildren = new aiNode*[src.children.size()];
- for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) {
- aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode();
- ndd->mParent = nd;
-
- BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Determine the exact location of a LWO file
-std::string LWSImporter::FindLWOFile(const std::string& in)
-{
- // insert missing directory seperator if necessary
- std::string tmp;
- if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
- {
- tmp = in[0] + ":\\" + in.substr(2);
- }
- else tmp = in;
-
- if (io->Exists(tmp))
- return in;
-
- // file is not accessible for us ... maybe it's packed by
- // LightWave's 'Package Scene' command?
-
- // Relevant for us are the following two directories:
- // <folder>\Objects\<hh>\<*>.lwo
- // <folder>\Scenes\<hh>\<*>.lws
- // where <hh> is optional.
-
- std::string test = ".." + io->getOsSeparator() + tmp;
- if (io->Exists(test))
- return test;
-
- test = ".." + io->getOsSeparator() + test;
- if (io->Exists(test))
- return test;
-
- // return original path, maybe the IOsystem knows better
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read file into given scene data structure
-void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler)
-{
- io = pIOHandler;
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open LWS file " + pFile + ".");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector< char > mBuffer;
- TextFileToBuffer(file.get(),mBuffer);
-
- // Parse the file structure
- LWS::Element root; const char* dummy = &mBuffer[0];
- root.Parse(dummy);
-
- // Construct a Batchimporter to read more files recursively
- BatchLoader batch(pIOHandler);
-// batch.SetBasePath(pFile);
-
- // Construct an array to receive the flat output graph
- std::list<LWS::NodeDesc> nodes;
-
- unsigned int cur_light = 0, cur_camera = 0, cur_object = 0;
- unsigned int num_light = 0, num_camera = 0, num_object = 0;
-
- // check magic identifier, 'LWSC'
- bool motion_file = false;
- std::list< LWS::Element >::const_iterator it = root.children.begin();
-
- if ((*it).tokens[0] == "LWMO")
- motion_file = true;
-
- if ((*it).tokens[0] != "LWSC" && !motion_file)
- throw DeadlyImportError("LWS: Not a LightWave scene, magic tag LWSC not found");
-
- // get file format version and print to log
- ++it;
- unsigned int version = strtol10((*it).tokens[0].c_str());
- DefaultLogger::get()->info("LWS file format version is " + (*it).tokens[0]);
- first = 0.;
- last = 60.;
- fps = 25.; /* seems to be a good default frame rate */
-
- // Now read all elements in a very straghtforward manner
- for (; it != root.children.end(); ++it) {
- const char* c = (*it).tokens[1].c_str();
-
- // 'FirstFrame': begin of animation slice
- if ((*it).tokens[0] == "FirstFrame") {
- if (150392. != first /* see SetupProperties() */)
- first = strtol10(c,&c)-1.; /* we're zero-based */
- }
-
- // 'LastFrame': end of animation slice
- else if ((*it).tokens[0] == "LastFrame") {
- if (150392. != last /* see SetupProperties() */)
- last = strtol10(c,&c)-1.; /* we're zero-based */
- }
-
- // 'FramesPerSecond': frames per second
- else if ((*it).tokens[0] == "FramesPerSecond") {
- fps = strtol10(c,&c);
- }
-
- // 'LoadObjectLayer': load a layer of a specific LWO file
- else if ((*it).tokens[0] == "LoadObjectLayer") {
-
- // get layer index
- const int layer = strtol10(c,&c);
-
- // setup the layer to be loaded
- BatchLoader::PropertyMap props;
- SetGenericProperty(props.ints,AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,layer);
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- if (version >= 4) { // handle LWSC 4 explicit ID
- SkipSpaces(&c);
- d.number = strtol16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_object++;
-
- // and add the file to the import list
- SkipSpaces(&c);
- std::string path = FindLWOFile( c );
- d.path = path;
- d.id = batch.AddLoadRequest(path,0,&props);
-
- nodes.push_back(d);
- num_object++;
- }
- // 'LoadObject': load a LWO file into the scenegraph
- else if ((*it).tokens[0] == "LoadObject") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtol16(c,&c) & AI_LWS_MASK;
- SkipSpaces(&c);
- }
- else d.number = cur_object++;
- std::string path = FindLWOFile( c );
- d.id = batch.AddLoadRequest(path,0,NULL);
-
- d.path = path;
- nodes.push_back(d);
- num_object++;
- }
- // 'AddNullObject': add a dummy node to the hierarchy
- else if ((*it).tokens[0] == "AddNullObject") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- d.name = c;
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtol16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_object++;
- nodes.push_back(d);
-
- num_object++;
- }
- // 'NumChannels': Number of envelope channels assigned to last layer
- else if ((*it).tokens[0] == "NumChannels") {
- // ignore for now
- }
- // 'Channel': preceedes any envelope description
- else if ((*it).tokens[0] == "Channel") {
- if (nodes.empty()) {
- if (motion_file) {
-
- // LightWave motion file. Add dummy node
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- d.name = c;
- d.number = cur_object++;
- nodes.push_back(d);
- }
- else DefaultLogger::get()->error("LWS: Unexpected keyword: \'Channel\'");
- }
-
- // important: index of channel
- nodes.back().channels.push_back(LWO::Envelope());
- LWO::Envelope& env = nodes.back().channels.back();
-
- env.index = strtol10(c);
-
- // currently we can just interpret the standard channels 0...9
- // (hack) assume that index-i yields the binary channel type from LWO
- env.type = (LWO::EnvelopeType)(env.index+1);
-
- }
- // 'Envelope': a single animation channel
- else if ((*it).tokens[0] == "Envelope") {
- if (nodes.empty() || nodes.back().channels.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'Envelope\'");
- else {
- ReadEnvelope((*it),nodes.back().channels.back());
- }
- }
- // 'ObjectMotion': animation information for older lightwave formats
- else if (version < 3 && ((*it).tokens[0] == "ObjectMotion" ||
- (*it).tokens[0] == "CameraMotion" ||
- (*it).tokens[0] == "LightMotion")) {
-
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
- else {
- ReadEnvelope_Old(it,root.children.end(),nodes.back(),version);
- }
- }
- // 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
- else if (version == 2 && (*it).tokens[0] == "Pre/PostBehavior") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'Pre/PostBehavior'");
- else {
- for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
- // two ints per envelope
- LWO::Envelope& env = *it;
- env.pre = (LWO::PrePostBehaviour) strtol10(c,&c); SkipSpaces(&c);
- env.post = (LWO::PrePostBehaviour) strtol10(c,&c); SkipSpaces(&c);
- }
- }
- }
- // 'ParentItem': specifies the parent of the current element
- else if ((*it).tokens[0] == "ParentItem") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentItem\'");
-
- else nodes.back().parent = strtol16(c,&c);
- }
- // 'ParentObject': deprecated one for older formats
- else if (version < 3 && (*it).tokens[0] == "ParentObject") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentObject\'");
-
- else {
- nodes.back().parent = strtol10(c,&c) | (1u << 28u);
- }
- }
- // 'AddCamera': add a camera to the scenegraph
- else if ((*it).tokens[0] == "AddCamera") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::CAMERA;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtol16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_camera++;
- nodes.push_back(d);
-
- num_camera++;
- }
- // 'CameraName': set name of currently active camera
- else if ((*it).tokens[0] == "CameraName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'CameraName\'");
-
- else nodes.back().name = c;
- }
- // 'AddLight': add a light to the scenegraph
- else if ((*it).tokens[0] == "AddLight") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::LIGHT;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtol16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_light++;
- nodes.push_back(d);
-
- num_light++;
- }
- // 'LightName': set name of currently active light
- else if ((*it).tokens[0] == "LightName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightName\'");
-
- else nodes.back().name = c;
- }
- // 'LightIntensity': set intensity of currently active light
- else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity" ) {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightIntensity\'");
-
- else fast_atof_move(c, nodes.back().lightIntensity );
-
- }
- // 'LightType': set type of currently active light
- else if ((*it).tokens[0] == "LightType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightType\'");
-
- else nodes.back().lightType = strtol10(c);
-
- }
- // 'LightFalloffType': set falloff type of currently active light
- else if ((*it).tokens[0] == "LightFalloffType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightFalloffType\'");
-
- else nodes.back().lightFalloffType = strtol10(c);
-
- }
- // 'LightConeAngle': set cone angle of currently active light
- else if ((*it).tokens[0] == "LightConeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightConeAngle\'");
-
- else nodes.back().lightConeAngle = fast_atof(c);
-
- }
- // 'LightEdgeAngle': set area where we're smoothing from min to max intensity
- else if ((*it).tokens[0] == "LightEdgeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightEdgeAngle\'");
-
- else nodes.back().lightEdgeAngle = fast_atof(c);
-
- }
- // 'LightColor': set color of currently active light
- else if ((*it).tokens[0] == "LightColor") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightColor\'");
-
- else {
- c = fast_atof_move(c, (float&) nodes.back().lightColor.r );
- SkipSpaces(&c);
- c = fast_atof_move(c, (float&) nodes.back().lightColor.g );
- SkipSpaces(&c);
- c = fast_atof_move(c, (float&) nodes.back().lightColor.b );
- }
- }
-
- // 'PivotPosition': position of local transformation origin
- else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'PivotPosition\'");
- else {
- c = fast_atof_move(c, (float&) nodes.back().pivotPos.x );
- SkipSpaces(&c);
- c = fast_atof_move(c, (float&) nodes.back().pivotPos.y );
- SkipSpaces(&c);
- c = fast_atof_move(c, (float&) nodes.back().pivotPos.z );
- }
- }
- }
-
- // resolve parenting
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
-
- // check whether there is another node which calls us a parent
- for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
- if (dit != it && *it == (*dit).parent) {
- if ((*dit).parent_resolved) {
- // fixme: it's still possible to produce an overflow due to cross references ..
- DefaultLogger::get()->error("LWS: Found cross reference in scenegraph");
- continue;
- }
-
- (*it).children.push_back(&*dit);
- (*dit).parent_resolved = &*it;
- }
- }
- }
-
- // find out how many nodes have no parent yet
- unsigned int no_parent = 0;
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
- if (!(*it).parent_resolved)
- ++ no_parent;
- }
- if (!no_parent)
- throw DeadlyImportError("LWS: Unable to find scene root node");
-
-
- // Load all subsequent files
- batch.LoadAll();
-
- // and build the final output graph by attaching the loaded external
- // files to ourselves. first build a master graph
- aiScene* master = new aiScene();
- aiNode* nd = master->mRootNode = new aiNode();
-
- // allocate storage for cameras&lights
- if (num_camera) {
- master->mCameras = new aiCamera*[master->mNumCameras = num_camera];
- }
- aiCamera** cams = master->mCameras;
- if (num_light) {
- master->mLights = new aiLight*[master->mNumLights = num_light];
- }
- aiLight** lights = master->mLights;
-
- std::vector<AttachmentInfo> attach;
- std::vector<aiNodeAnim*> anims;
-
- nd->mName.Set("<LWSRoot>");
- nd->mChildren = new aiNode*[no_parent];
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
- if (!(*it).parent_resolved) {
- aiNode* ro = nd->mChildren[ nd->mNumChildren++ ] = new aiNode();
- ro->mParent = nd;
-
- // ... and build the scene graph. If we encounter object nodes,
- // add then to our attachment table.
- BuildGraph(ro,*it, attach, batch, cams, lights, anims);
- }
- }
-
- // create a master animation channel for us
- if (anims.size()) {
- master->mAnimations = new aiAnimation*[master->mNumAnimations = 1];
- aiAnimation* anim = master->mAnimations[0] = new aiAnimation();
- anim->mName.Set("LWSMasterAnim");
-
- // LWS uses seconds as time units, but we convert to frames
- anim->mTicksPerSecond = fps;
- anim->mDuration = last-(first-1); /* fixme ... zero or one-based?*/
-
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels = anims.size()];
- std::copy(anims.begin(),anims.end(),anim->mChannels);
- }
-
- // convert the master scene to RH
- MakeLeftHandedProcess monster_cheat;
- monster_cheat.Execute(master);
-
- // .. ccw
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-
- // OK ... finally build the output graph
- SceneCombiner::MergeScenes(&pScene,master,attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
-
- // Check flags
- if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
-
- if (pScene->mNumAnimations) {
- // construct skeleton mesh
- SkeletonMeshBuilder builder(pScene);
- }
- }
-
-}
diff --git a/3rdparty/assimp/code/LWSLoader.h b/3rdparty/assimp/code/LWSLoader.h
deleted file mode 100644
index 40eb525a..00000000
--- a/3rdparty/assimp/code/LWSLoader.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file LWSLoader.h
- * @brief Declaration of the LightWave scene importer class.
- */
-#ifndef AI_LWSLOADER_H_INCLUDED
-#define AI_LWSLOADER_H_INCLUDED
-
-#include "LWOFileData.h"
-#include "SceneCombiner.h"
-
-namespace Assimp {
- namespace LWS {
-
-// ---------------------------------------------------------------------------
-/** Represents an element in a LWS file.
- *
- * This can either be a single data line - <name> <value> or a data
- * group - { name <data_line0> ... n }
- */
-class Element
-{
-public:
- Element()
- {}
-
- // first: name, second: rest
- std::string tokens[2];
- std::list<Element> children;
-
- //! Recursive parsing function
- void Parse (const char*& buffer);
-};
-
-#define AI_LWS_MASK (0xffffffff >> 4u)
-
-// ---------------------------------------------------------------------------
-/** Represents a LWS scenegraph element
- */
-struct NodeDesc
-{
- NodeDesc()
- : number (0)
- , parent (0)
- , name ("")
- , lightColor (1.f,1.f,1.f)
- , lightIntensity (1.f)
- , lightType (0)
- , lightFalloffType (0)
- , lightConeAngle (45.f)
- , parent_resolved (NULL)
- {}
-
- enum {
-
- OBJECT = 1,
- LIGHT = 2,
- CAMERA = 3,
- BONE = 4
- } type; // type of node
-
- // if object: path
- std::string path;
- unsigned int id;
-
- // number of object
- unsigned int number;
-
- // index of parent index
- unsigned int parent;
-
- // lights & cameras & dummies: name
- const char* name;
-
- // animation channels
- std::list< LWO::Envelope > channels;
-
- // position of pivot point
- aiVector3D pivotPos;
-
-
-
- // color of light source
- aiColor3D lightColor;
-
- // intensity of light source
- float lightIntensity;
-
- // type of light source
- unsigned int lightType;
-
- // falloff type of light source
- unsigned int lightFalloffType;
-
- // cone angle of (spot) light source
- float lightConeAngle;
-
- // soft cone angle of (spot) light source
- float lightEdgeAngle;
-
-
-
- // list of resolved children
- std::list< NodeDesc* > children;
-
- // resolved parent node
- NodeDesc* parent_resolved;
-
-
- // for std::find()
- bool operator == (unsigned int num) const {
- if (!num)
- return false;
- unsigned int _type = num >> 28u;
-
- return _type == static_cast<unsigned int>(type) && (num & AI_LWS_MASK) == number;
- }
-};
-
-} // end namespace LWS
-
-// ---------------------------------------------------------------------------
-/** LWS (LightWave Scene Format) importer class.
- *
- * This class does heavily depend on the LWO importer class. LWS files
- * contain mainly descriptions how LWO objects are composed together
- * in a scene.
-*/
-class LWSImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- LWSImporter();
-
- /** Destructor, private as well */
- ~LWSImporter();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether we can read a specific file
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- // Get list of supported extensions
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- // Import file into given scene data structure
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- // Setup import properties
- void SetupProperties(const Importer* pImp);
-
-private:
-
-
- // -------------------------------------------------------------------
- // Read an envelope description
- void ReadEnvelope(const LWS::Element& dad, LWO::Envelope& out );
-
- // -------------------------------------------------------------------
- // Read an envelope description for the older LW file format
- void ReadEnvelope_Old(std::list< LWS::Element >::const_iterator& it,
- const std::list< LWS::Element >::const_iterator& end,
- LWS::NodeDesc& nodes,
- unsigned int version);
-
- // -------------------------------------------------------------------
- // Setup a nice name for a node
- void SetupNodeName(aiNode* nd, LWS::NodeDesc& src);
-
- // -------------------------------------------------------------------
- // Recursively build the scenegraph
- void BuildGraph(aiNode* nd,
- LWS::NodeDesc& src,
- std::vector<AttachmentInfo>& attach,
- BatchLoader& batch,
- aiCamera**& camOut,
- aiLight**& lightOut,
- std::vector<aiNodeAnim*>& animOut);
-
- // -------------------------------------------------------------------
- // Try several dirs until we find the right location of a LWS file.
- std::string FindLWOFile(const std::string& in);
-
-private:
-
- bool configSpeedFlag;
- IOSystem* io;
-
- double first,last,fps;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_LWSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp b/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp
deleted file mode 100644
index e919567d..00000000
--- a/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** Implementation of the LimitBoneWeightsProcess post processing step */
-
-#include "AssimpPCH.h"
-#include "LimitBoneWeightsProcess.h"
-
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LimitBoneWeightsProcess::LimitBoneWeightsProcess()
-{
- mMaxWeights = AI_LMW_MAX_WEIGHTS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LimitBoneWeightsProcess::~LimitBoneWeightsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_LimitBoneWeights) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void LimitBoneWeightsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("LimitBoneWeightsProcess begin");
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- ProcessMesh( pScene->mMeshes[a]);
-
- DefaultLogger::get()->debug("LimitBoneWeightsProcess end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
-{
- // get the current value of the property
- this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unites identical vertices in the given mesh
-void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
-{
- if ( !pMesh->HasBones())
- return;
-
- // collect all bone weights per vertex
- typedef std::vector< std::vector< Weight > > WeightsPerVertex;
- WeightsPerVertex vertexWeights( pMesh->mNumVertices);
-
- // collect all weights per vertex
- for ( unsigned int a = 0; a < pMesh->mNumBones; a++)
- {
- const aiBone* bone = pMesh->mBones[a];
- for ( unsigned int b = 0; b < bone->mNumWeights; b++)
- {
- const aiVertexWeight& w = bone->mWeights[b];
- vertexWeights[w.mVertexId].push_back( Weight( a, w.mWeight));
- }
- }
-
- unsigned int removed = 0, old_bones = pMesh->mNumBones;
-
- // now cut the weight count if it exceeds the maximum
- bool bChanged = false;
- for ( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
- {
- if ( vit->size() <= mMaxWeights)
- continue;
-
- bChanged = true;
-
- // more than the defined maximum -> first sort by weight in descending order. That's
- // why we defined the < operator in such a weird way.
- std::sort( vit->begin(), vit->end());
-
- // now kill everything beyond the maximum count
- unsigned int m = vit->size();
- vit->erase( vit->begin() + mMaxWeights, vit->end());
- removed += m-vit->size();
-
- // and renormalize the weights
- float sum = 0.0f;
- for ( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it)
- sum += it->mWeight;
- for ( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it)
- it->mWeight /= sum;
- }
-
- if (bChanged) {
- // rebuild the vertex weight array for all bones
- typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
- WeightsPerBone boneWeights( pMesh->mNumBones);
- for ( unsigned int a = 0; a < vertexWeights.size(); a++)
- {
- const std::vector<Weight>& vw = vertexWeights[a];
- for ( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
- boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
- }
-
- // and finally copy the vertex weight list over to the mesh's bones
- std::vector<bool> abNoNeed(pMesh->mNumBones,false);
- bChanged = false;
-
- for ( unsigned int a = 0; a < pMesh->mNumBones; a++)
- {
- const std::vector<aiVertexWeight>& bw = boneWeights[a];
- aiBone* bone = pMesh->mBones[a];
-
- // ignore the bone if no vertex weights were removed there
-
- // FIX (Aramis, 07|22|08)
- // NO! we can't ignore it in this case ... it is possible that
- // the number of weights did not change, but the weight values did.
-
- // if ( bw.size() == bone->mNumWeights)
- // continue;
-
- // FIX (Aramis, 07|21|08)
- // It is possible that all weights of a bone have been removed.
- // This would naturally cause an exception in &bw[0].
- if ( bw.empty() )
- {
- abNoNeed[a] = bChanged = true;
- continue;
- }
-
- // copy the weight list. should always be less weights than before, so we don't need a new allocation
- ai_assert( bw.size() <= bone->mNumWeights);
- bone->mNumWeights = (unsigned int) bw.size();
- ::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
- }
-
- if (bChanged) {
- // the number of new bones is smaller than before, so we can reuse the old array
- aiBone** ppcCur = pMesh->mBones;aiBone** ppcSrc = ppcCur;
-
- for (std::vector<bool>::const_iterator iter = abNoNeed.begin();iter != abNoNeed.end() ;++iter) {
- if (*iter) {
- delete *ppcSrc;
- --pMesh->mNumBones;
- }
- else *ppcCur++ = *ppcSrc;
- ++ppcSrc;
- }
- }
-
- if (!DefaultLogger::isNullLogger()) {
- char buffer[1024];
- ::sprintf(buffer,"Removed %i weights. Input bones: %i. Output bones: %i",removed,old_bones,pMesh->mNumBones);
- DefaultLogger::get()->info(buffer);
- }
- }
-}
diff --git a/3rdparty/assimp/code/LimitBoneWeightsProcess.h b/3rdparty/assimp/code/LimitBoneWeightsProcess.h
deleted file mode 100644
index 91007d3e..00000000
--- a/3rdparty/assimp/code/LimitBoneWeightsProcess.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** Defines a post processing step to limit the number of bones affecting a single vertex. */
-#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
-#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-class LimitBoneWeightsTest;
-
-namespace Assimp
-{
-
-// NOTE: If you change these limits, don't forget to change the
-// corresponding values in all Assimp ports
-
-// **********************************************************
-// Java: ConfigProperty.java,
-// ConfigProperty.DEFAULT_BONE_WEIGHT_LIMIT
-// **********************************************************
-
-#if (!defined AI_LMW_MAX_WEIGHTS)
-# define AI_LMW_MAX_WEIGHTS 0x4
-#endif // !! AI_LMW_MAX_WEIGHTS
-
-// ---------------------------------------------------------------------------
-/** This post processing step limits the number of bones affecting a vertex
-* to a certain maximum value. If a vertex is affected by more than that number
-* of bones, the bone weight with the least influence on this vertex are removed.
-* The other weights on this bone are then renormalized to assure the sum weight
-* to be 1.
-*/
-class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::LimitBoneWeightsTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- LimitBoneWeightsProcess();
-
- /** Destructor, private as well */
- ~LimitBoneWeightsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Limits the bone weight count for all vertices in the given mesh.
- * @param pMesh The mesh to process.
- */
- void ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
-protected:
-
- // -------------------------------------------------------------------
- /** Describes a bone weight on a vertex */
- struct Weight
- {
- unsigned int mBone; ///< Index of the bone
- float mWeight; ///< Weight of that bone on this vertex
- Weight() { }
- Weight( unsigned int pBone, float pWeight)
- {
- mBone = pBone;
- mWeight = pWeight;
- }
-
- /** Comparision operator to sort bone weights by descending weight */
- bool operator < (const Weight& pWeight) const
- {
- return mWeight > pWeight.mWeight;
- }
- };
-
-public:
- /** Maximum number of bones influencing any single vertex. */
- unsigned int mMaxWeights;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_LIMITBONEWEIGHTSPROCESS_H_INC
diff --git a/3rdparty/assimp/code/LineSplitter.h b/3rdparty/assimp/code/LineSplitter.h
deleted file mode 100644
index 47f69d82..00000000
--- a/3rdparty/assimp/code/LineSplitter.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file LineSplitter.h
- * @brief LineSplitter, a helper class to iterate through all lines
- * of a file easily. Works with StreamReader.
- */
-#ifndef INCLUDED_LINE_SPLITTER_H
-#define INCLUDED_LINE_SPLITTER_H
-
-#include <stdexcept>
-
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/** Usage:
-@code
-for (LineSplitter splitter(stream);splitter;++splitter) {
-
- if (*splitter == "hi!") {
- ...
- }
- else if (splitter->substr(0,5) == "hello") {
- ...
- // access the third token in the line (tokens are space-separated)
- if (strtol(splitter[2]) > 5) { .. }
- }
-
- std::cout << "Current line is: " << splitter.get_index() << std::endl;
-}
-@endcode */
-// ------------------------------------------------------------------------------------------------
-class LineSplitter
-{
-public:
-
- typedef size_t line_idx;
-
-public:
-
- // -----------------------------------------
- /** construct from existing stream reader */
- LineSplitter(StreamReaderLE& stream)
- : stream(stream)
- , swallow()
- {
- cur.reserve(1024);
- operator++();
-
- idx = 0;
- }
-
-public:
-
- // -----------------------------------------
- /** pseudo-iterator increment */
- LineSplitter& operator++() {
- if (swallow) {
- swallow = false;
- return *this;
- }
-
- if (!*this) {
- throw std::logic_error("End of file, no more lines to be retrieved.");
- }
-
- char s;
-
- cur.clear(); // I will kill you if you deallocate.
- while (stream.GetRemainingSize() && (s = stream.GetI1(),1)) {
- if (s == '\n' || s == '\r') {
- while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\r' || s == '\n')) {};
- if (stream.GetRemainingSize()) {
- stream.IncPtr(-1);
- }
- break;
- }
- cur += s;
- }
-
- ++idx;
- return *this;
- }
-
- // -----------------------------------------
- /** get a pointer to the beginning of a particular token */
- const char* operator[] (size_t idx) const {
- const char* s = operator->()->c_str();
-
- SkipSpaces(&s);
- for (size_t i = 0; i < idx; ++i) {
-
- for (;!IsSpace(*s); ++s) {
- if (IsLineEnd(*s)) {
- throw std::range_error("Token index out of range, EOL reached");
- }
- }
- SkipSpaces(&s);
- }
- return s;
- }
-
- // -----------------------------------------
- /** extract the start positions of N tokens from the current line*/
- template <size_t N>
- void get_tokens(const char* (&tokens)[N]) const {
- const char* s = operator->()->c_str();
-
- SkipSpaces(&s);
- for (size_t i = 0; i < N; ++i) {
- if (IsLineEnd(*s)) {
- throw std::range_error("Token count out of range, EOL reached");
- }
- tokens[i] = s;
-
- for (;*s && !IsSpace(*s); ++s) {};
- SkipSpaces(&s);
- }
- }
-
- // -----------------------------------------
- /** member access */
- const std::string* operator -> () const {
- return &cur;
- }
-
- const std::string& operator* () const {
- return cur;
- }
-
- // -----------------------------------------
- /** boolean context */
- operator bool() const {
- return stream.GetRemainingSize()>0;
- }
-
- // -----------------------------------------
- /** line indices are zero-based, empty lines are included */
- operator line_idx() const {
- return idx;
- }
-
- line_idx get_index() const {
- return idx;
- }
-
- // -----------------------------------------
- /** access the underlying stream object */
- StreamReaderLE& get_stream() {
- return stream;
- }
-
- // -----------------------------------------
- /** !strcmp((*this)->substr(0,strlen(check)),check) */
- bool match_start(const char* check) {
- const size_t len = strlen(check);
-
- return len <= cur.length() && std::equal(check,check+len,cur.begin());
- }
-
-
- // -----------------------------------------
- /** swallow the next call to ++, return the previous value. */
- void swallow_next_increment() {
- swallow = true;
- }
-
-private:
-
- line_idx idx;
- std::string cur;
- StreamReaderLE& stream;
- bool swallow;
-};
-
-}
-#endif // INCLUDED_LINE_SPLITTER_H
diff --git a/3rdparty/assimp/code/MD2FileData.h b/3rdparty/assimp/code/MD2FileData.h
deleted file mode 100644
index 661e176c..00000000
--- a/3rdparty/assimp/code/MD2FileData.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MD2FileData.h
- * @brief Defines helper data structures for importing MD2 files
- * http://linux.ucla.edu/~phaethon/q3/formats/md2-schoenblum.html
- */
-#ifndef AI_MD2FILEHELPER_H_INC
-#define AI_MD2FILEHELPER_H_INC
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-#include "./../include/Compiler/pushpack1.h"
-
-namespace Assimp {
-namespace MD2 {
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MD2_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP2")
-#define AI_MD2_MAGIC_NUMBER_LE AI_MAKE_MAGIC("2PDI")
-
-// common limitations
-#define AI_MD2_VERSION 15
-#define AI_MD2_MAXQPATH 64
-#define AI_MD2_MAX_FRAMES 512
-#define AI_MD2_MAX_SKINS 32
-#define AI_MD2_MAX_VERTS 2048
-#define AI_MD2_MAX_TRIANGLES 4096
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for the MD2 main header
- */
-struct Header
-{
- uint32_t magic;
- uint32_t version;
- uint32_t skinWidth;
- uint32_t skinHeight;
- uint32_t frameSize;
- uint32_t numSkins;
- uint32_t numVertices;
- uint32_t numTexCoords;
- uint32_t numTriangles;
- uint32_t numGlCommands;
- uint32_t numFrames;
- uint32_t offsetSkins;
- uint32_t offsetTexCoords;
- uint32_t offsetTriangles;
- uint32_t offsetFrames;
- uint32_t offsetGlCommands;
- uint32_t offsetEnd;
-
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 OpenGl draw command
- */
-struct GLCommand
-{
- float s, t;
- uint32_t vertexIndex;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 triangle
- */
-struct Triangle
-{
- uint16_t vertexIndices[3];
- uint16_t textureIndices[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 vertex
- */
-struct Vertex
-{
- uint8_t vertex[3];
- uint8_t lightNormalIndex;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 frame
- */
-struct Frame
-{
- float scale[3];
- float translate[3];
- char name[16];
- Vertex vertices[1];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 texture coordinate
- */
-struct TexCoord
-{
- uint16_t s;
- uint16_t t;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 skin
- */
-struct Skin
-{
- char name[AI_MD2_MAXQPATH]; /* texture file name */
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-
-// ---------------------------------------------------------------------------
-//! Lookup a normal vector from Quake's normal lookup table
-//! \param index Input index (0-161)
-//! \param vOut Receives the output normal
-void LookupNormalIndex(uint8_t index,aiVector3D& vOut);
-
-
-}
-}
-
-#endif // !! include guard
-
diff --git a/3rdparty/assimp/code/MD2Loader.cpp b/3rdparty/assimp/code/MD2Loader.cpp
deleted file mode 100644
index cb85c9da..00000000
--- a/3rdparty/assimp/code/MD2Loader.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
-
-/** @file Implementation of the MD2 importer class */
-#include "MD2Loader.h"
-#include "MaterialSystem.h"
-#include "ByteSwap.h"
-#include "MD2NormalTable.h" // shouldn't be included by other units
-
-using namespace Assimp;
-using namespace Assimp::MD2;
-
-
-// helper macro to determine the size of an array
-#if (!defined ARRAYSIZE)
-# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to lookup a normal in Quake 2's precalculated table
-void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
-{
- // make sure the normal index has a valid value
- if (iNormalIndex >= ARRAYSIZE(g_avNormals)) {
- DefaultLogger::get()->warn("Index overflow in Quake II normal vector list");
- iNormalIndex = ARRAYSIZE(g_avNormals) - 1;
- }
- vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex]));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD2Importer::MD2Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD2Importer::~MD2Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "md2")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MD2_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all extensions supported by this loader
-void MD2Importer::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("md2");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MD2Importer::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD2_KEYFRAME,0xffffffff);
- if (0xffffffff == configFrameID){
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Validate the file header
-void MD2Importer::ValidateHeader( )
-{
- // check magic number
- if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
- m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
- {
- char szBuffer[5];
- szBuffer[0] = ((char*)&m_pcHeader->magic)[0];
- szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
- szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
- szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
- szBuffer[4] = '\0';
-
- throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
- "magic word found is " + std::string(szBuffer));
- }
-
- // check file format version
- if (m_pcHeader->version != 8)
- DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
-
- // check some values whether they are valid
- if (0 == m_pcHeader->numFrames)
- throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0");
-
- if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
- throw DeadlyImportError( "Invalid md2 file: File is too small");
-
- if (m_pcHeader->offsetSkins + m_pcHeader->numSkins * sizeof (MD2::Skin) >= fileSize ||
- m_pcHeader->offsetTexCoords + m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= fileSize ||
- m_pcHeader->offsetTriangles + m_pcHeader->numTriangles * sizeof (MD2::Triangle) >= fileSize ||
- m_pcHeader->offsetFrames + m_pcHeader->numFrames * sizeof (MD2::Frame) >= fileSize ||
- m_pcHeader->offsetEnd > fileSize)
- {
- throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file");
- }
-
- if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
- DefaultLogger::get()->warn("The model contains more skins than Quake 2 supports");
- if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES)
- DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
- if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
- DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
-
- if (m_pcHeader->numFrames <= configFrameID )
- throw DeadlyImportError("The requested frame is not existing the file");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD2Importer::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MD2 file " + pFile + "");
-
- // check whether the md3 file is large enough to contain
- // at least the file header
- fileSize = (unsigned int)file->FileSize();
- if ( fileSize < sizeof(MD2::Header))
- throw DeadlyImportError( "MD2 File is too small");
-
- std::vector<uint8_t> mBuffer2(fileSize);
- file->Read(&mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
-
- m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
-
-#ifdef AI_BUILD_BIG_ENDIAN
-
- ByteSwap::Swap4(&m_pcHeader->frameSize);
- ByteSwap::Swap4(&m_pcHeader->magic);
- ByteSwap::Swap4(&m_pcHeader->numFrames);
- ByteSwap::Swap4(&m_pcHeader->numGlCommands);
- ByteSwap::Swap4(&m_pcHeader->numSkins);
- ByteSwap::Swap4(&m_pcHeader->numTexCoords);
- ByteSwap::Swap4(&m_pcHeader->numTriangles);
- ByteSwap::Swap4(&m_pcHeader->numVertices);
- ByteSwap::Swap4(&m_pcHeader->offsetEnd);
- ByteSwap::Swap4(&m_pcHeader->offsetFrames);
- ByteSwap::Swap4(&m_pcHeader->offsetGlCommands);
- ByteSwap::Swap4(&m_pcHeader->offsetSkins);
- ByteSwap::Swap4(&m_pcHeader->offsetTexCoords);
- ByteSwap::Swap4(&m_pcHeader->offsetTriangles);
- ByteSwap::Swap4(&m_pcHeader->skinHeight);
- ByteSwap::Swap4(&m_pcHeader->skinWidth);
- ByteSwap::Swap4(&m_pcHeader->version);
-
-#endif
-
- ValidateHeader();
-
- // there won't be more than one mesh inside the file
- pScene->mNumMaterials = 1;
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = new MaterialHelper();
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
-
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // navigate to the begin of the frame data
- BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetFrames);
-
- pcFrame += configFrameID;
-
- // navigate to the begin of the triangle data
- MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetTriangles);
-
- // navigate to the begin of the tex coords data
- BE_NCONST MD2::TexCoord* pcTexCoords = (BE_NCONST MD2::TexCoord*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetTexCoords);
-
- // navigate to the begin of the vertex data
- BE_NCONST MD2::Vertex* pcVerts = (BE_NCONST MD2::Vertex*) (pcFrame->vertices);
-
-#ifdef AI_BUILD_BIG_ENDIAN
- for (uint32_t i = 0; i< m_pcHeader->numTriangles; ++i)
- {
- for (unsigned int p = 0; p < 3;++p)
- {
- ByteSwap::Swap2(& pcTriangles[i].textureIndices[p]);
- ByteSwap::Swap2(& pcTriangles[i].vertexIndices[p]);
- }
- }
- for (uint32_t i = 0; i < m_pcHeader->offsetTexCoords;++i)
- {
- ByteSwap::Swap2(& pcTexCoords[i].s);
- ByteSwap::Swap2(& pcTexCoords[i].t);
- }
- ByteSwap::Swap4( & pcFrame->scale[0] );
- ByteSwap::Swap4( & pcFrame->scale[1] );
- ByteSwap::Swap4( & pcFrame->scale[2] );
- ByteSwap::Swap4( & pcFrame->translate[0] );
- ByteSwap::Swap4( & pcFrame->translate[1] );
- ByteSwap::Swap4( & pcFrame->translate[2] );
-#endif
-
- pcMesh->mNumFaces = m_pcHeader->numTriangles;
- pcMesh->mFaces = new aiFace[m_pcHeader->numTriangles];
-
- // allocate output storage
- pcMesh->mNumVertices = (unsigned int)pcMesh->mNumFaces*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- // Not sure whether there are MD2 files without texture coordinates
- // NOTE: texture coordinates can be there without a texture,
- // but a texture can't be there without a valid UV channel
- MaterialHelper* pcHelper = (MaterialHelper*)pScene->mMaterials[0];
- const int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- if (m_pcHeader->numTexCoords && m_pcHeader->numSkins)
- {
- // navigate to the first texture associated with the mesh
- const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)m_pcHeader +
- m_pcHeader->offsetSkins);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- if (pcSkins->name[0])
- {
- aiString szString;
- const size_t iLen = ::strlen(pcSkins->name);
- ::memcpy(szString.data,pcSkins->name,iLen);
- szString.data[iLen] = '\0';
- szString.length = iLen;
-
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else{
- DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped.");
- }
- }
- else {
- // apply a default material
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_TEXTURED_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- aiString sz;
-
- // TODO: Try to guess the name of the texture file from the model file name
-
- sz.Set("$texture_dummy.bmp");
- pcHelper->AddProperty(&sz,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
-
-
- // now read all triangles of the first frame, apply scaling and translation
- unsigned int iCurrent = 0;
-
- float fDivisorU = 1.0f,fDivisorV = 1.0f;
- if (m_pcHeader->numTexCoords) {
- // allocate storage for texture coordinates, too
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // check whether the skin width or height are zero (this would
- // cause a division through zero)
- if (!m_pcHeader->skinWidth) {
- DefaultLogger::get()->error("MD2: No valid skin width given");
- }
- else fDivisorU = (float)m_pcHeader->skinWidth;
- if (!m_pcHeader->skinHeight){
- DefaultLogger::get()->error("MD2: No valid skin height given");
- }
- else fDivisorV = (float)m_pcHeader->skinHeight;
- }
-
- for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i) {
- // Allocate the face
- pScene->mMeshes[0]->mFaces[i].mIndices = new unsigned int[3];
- pScene->mMeshes[0]->mFaces[i].mNumIndices = 3;
-
- // copy texture coordinates
- // check whether they are different from the previous value at this index.
- // In this case, create a full separate set of vertices/normals/texcoords
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
-
- // validate vertex indices
- register unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
- if (iIndex >= m_pcHeader->numVertices) {
- DefaultLogger::get()->error("MD2: Vertex index is outside the allowed range");
- iIndex = m_pcHeader->numVertices-1;
- }
-
- // read x,y, and z component of the vertex
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
-
- vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
- vec.x += pcFrame->translate[0];
-
- vec.y = (float)pcVerts[iIndex].vertex[1] * pcFrame->scale[1];
- vec.y += pcFrame->translate[1];
-
- vec.z = (float)pcVerts[iIndex].vertex[2] * pcFrame->scale[2];
- vec.z += pcFrame->translate[2];
-
- // read the normal vector from the precalculated normal table
- aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
- LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
-
- // flip z and y to become right-handed
- std::swap((float&)vNormal.z,(float&)vNormal.y);
- std::swap((float&)vec.z,(float&)vec.y);
-
- if (m_pcHeader->numTexCoords) {
- // validate texture coordinates
- iIndex = pcTriangles[i].textureIndices[c];
- if (iIndex >= m_pcHeader->numTexCoords) {
- DefaultLogger::get()->error("MD2: UV index is outside the allowed range");
- iIndex = m_pcHeader->numTexCoords-1;
- }
-
- aiVector3D& pcOut = pcMesh->mTextureCoords[0][iCurrent];
-
- // the texture coordinates are absolute values but we
- // need relative values between 0 and 1
- pcOut.x = pcTexCoords[iIndex].s / fDivisorU;
- pcOut.y = 1.f-pcTexCoords[iIndex].t / fDivisorV;
- }
- pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER
diff --git a/3rdparty/assimp/code/MD2Loader.h b/3rdparty/assimp/code/MD2Loader.h
deleted file mode 100644
index fe875580..00000000
--- a/3rdparty/assimp/code/MD2Loader.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MD2Loader.h
- * @brief Declaration of the .MD2 importer class.
- */
-#ifndef AI_MD2LOADER_H_INCLUDED
-#define AI_MD2LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-struct aiNode;
-#include "MD2FileData.h"
-
-namespace Assimp {
-class MaterialHelper;
-
-using namespace MD2;
-
-// ---------------------------------------------------------------------------
-/** Importer class for MD2
-*/
-class MD2Importer : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- MD2Importer();
-
- /** Destructor, private as well */
- ~MD2Importer();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
- // -------------------------------------------------------------------
- /** Validate the header of the file
- */
- void ValidateHeader();
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Header of the MD2 file */
- BE_NCONST MD2::Header* m_pcHeader;
-
- /** Buffer to hold the loaded file */
- BE_NCONST uint8_t* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/MD2NormalTable.h b/3rdparty/assimp/code/MD2NormalTable.h
deleted file mode 100644
index 9c795c2d..00000000
--- a/3rdparty/assimp/code/MD2NormalTable.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/*
- * @file Slightly modified version of the anorms.h header file
- * released by ID software with the Quake 2 source code.
- *
- * Table of normals used by MD2 models
- */
-
-#ifndef AI_MDL_NORMALTABLE_H_INC
-#define AI_MDL_NORMALTABLE_H_INC
-
-
-float g_avNormals[162][3] = {
-{ -0.525731f, 0.000000f, 0.850651f },
-{ -0.442863f, 0.238856f, 0.864188f },
-{ -0.295242f, 0.000000f, 0.955423f },
-{ -0.309017f, 0.500000f, 0.809017f },
-{ -0.162460f, 0.262866f, 0.951056f },
-{ 0.000000f, 0.000000f, 1.000000f },
-{ 0.000000f, 0.850651f, 0.525731f },
-{ -0.147621f, 0.716567f, 0.681718f },
-{ 0.147621f, 0.716567f, 0.681718f },
-{ 0.000000f, 0.525731f, 0.850651f },
-{ 0.309017f, 0.500000f, 0.809017f },
-{ 0.525731f, 0.000000f, 0.850651f },
-{ 0.295242f, 0.000000f, 0.955423f },
-{ 0.442863f, 0.238856f, 0.864188f },
-{ 0.162460f, 0.262866f, 0.951056f },
-{ -0.681718f, 0.147621f, 0.716567f },
-{ -0.809017f, 0.309017f, 0.500000f },
-{ -0.587785f, 0.425325f, 0.688191f },
-{ -0.850651f, 0.525731f, 0.000000f },
-{ -0.864188f, 0.442863f, 0.238856f },
-{ -0.716567f, 0.681718f, 0.147621f },
-{ -0.688191f, 0.587785f, 0.425325f },
-{ -0.500000f, 0.809017f, 0.309017f },
-{ -0.238856f, 0.864188f, 0.442863f },
-{ -0.425325f, 0.688191f, 0.587785f },
-{ -0.716567f, 0.681718f, -0.147621f },
-{ -0.500000f, 0.809017f, -0.309017f },
-{ -0.525731f, 0.850651f, 0.000000f },
-{ 0.000000f, 0.850651f, -0.525731f },
-{ -0.238856f, 0.864188f, -0.442863f },
-{ 0.000000f, 0.955423f, -0.295242f },
-{ -0.262866f, 0.951056f, -0.162460f },
-{ 0.000000f, 1.000000f, 0.000000f },
-{ 0.000000f, 0.955423f, 0.295242f },
-{ -0.262866f, 0.951056f, 0.162460f },
-{ 0.238856f, 0.864188f, 0.442863f },
-{ 0.262866f, 0.951056f, 0.162460f },
-{ 0.500000f, 0.809017f, 0.309017f },
-{ 0.238856f, 0.864188f, -0.442863f },
-{ 0.262866f, 0.951056f, -0.162460f },
-{ 0.500000f, 0.809017f, -0.309017f },
-{ 0.850651f, 0.525731f, 0.000000f },
-{ 0.716567f, 0.681718f, 0.147621f },
-{ 0.716567f, 0.681718f, -0.147621f },
-{ 0.525731f, 0.850651f, 0.000000f },
-{ 0.425325f, 0.688191f, 0.587785f },
-{ 0.864188f, 0.442863f, 0.238856f },
-{ 0.688191f, 0.587785f, 0.425325f },
-{ 0.809017f, 0.309017f, 0.500000f },
-{ 0.681718f, 0.147621f, 0.716567f },
-{ 0.587785f, 0.425325f, 0.688191f },
-{ 0.955423f, 0.295242f, 0.000000f },
-{ 1.000000f, 0.000000f, 0.000000f },
-{ 0.951056f, 0.162460f, 0.262866f },
-{ 0.850651f, -0.525731f, 0.000000f },
-{ 0.955423f, -0.295242f, 0.000000f },
-{ 0.864188f, -0.442863f, 0.238856f },
-{ 0.951056f, -0.162460f, 0.262866f },
-{ 0.809017f, -0.309017f, 0.500000f },
-{ 0.681718f, -0.147621f, 0.716567f },
-{ 0.850651f, 0.000000f, 0.525731f },
-{ 0.864188f, 0.442863f, -0.238856f },
-{ 0.809017f, 0.309017f, -0.500000f },
-{ 0.951056f, 0.162460f, -0.262866f },
-{ 0.525731f, 0.000000f, -0.850651f },
-{ 0.681718f, 0.147621f, -0.716567f },
-{ 0.681718f, -0.147621f, -0.716567f },
-{ 0.850651f, 0.000000f, -0.525731f },
-{ 0.809017f, -0.309017f, -0.500000f },
-{ 0.864188f, -0.442863f, -0.238856f },
-{ 0.951056f, -0.162460f, -0.262866f },
-{ 0.147621f, 0.716567f, -0.681718f },
-{ 0.309017f, 0.500000f, -0.809017f },
-{ 0.425325f, 0.688191f, -0.587785f },
-{ 0.442863f, 0.238856f, -0.864188f },
-{ 0.587785f, 0.425325f, -0.688191f },
-{ 0.688191f, 0.587785f, -0.425325f },
-{ -0.147621f, 0.716567f, -0.681718f },
-{ -0.309017f, 0.500000f, -0.809017f },
-{ 0.000000f, 0.525731f, -0.850651f },
-{ -0.525731f, 0.000000f, -0.850651f },
-{ -0.442863f, 0.238856f, -0.864188f },
-{ -0.295242f, 0.000000f, -0.955423f },
-{ -0.162460f, 0.262866f, -0.951056f },
-{ 0.000000f, 0.000000f, -1.000000f },
-{ 0.295242f, 0.000000f, -0.955423f },
-{ 0.162460f, 0.262866f, -0.951056f },
-{ -0.442863f, -0.238856f, -0.864188f },
-{ -0.309017f, -0.500000f, -0.809017f },
-{ -0.162460f, -0.262866f, -0.951056f },
-{ 0.000000f, -0.850651f, -0.525731f },
-{ -0.147621f, -0.716567f, -0.681718f },
-{ 0.147621f, -0.716567f, -0.681718f },
-{ 0.000000f, -0.525731f, -0.850651f },
-{ 0.309017f, -0.500000f, -0.809017f },
-{ 0.442863f, -0.238856f, -0.864188f },
-{ 0.162460f, -0.262866f, -0.951056f },
-{ 0.238856f, -0.864188f, -0.442863f },
-{ 0.500000f, -0.809017f, -0.309017f },
-{ 0.425325f, -0.688191f, -0.587785f },
-{ 0.716567f, -0.681718f, -0.147621f },
-{ 0.688191f, -0.587785f, -0.425325f },
-{ 0.587785f, -0.425325f, -0.688191f },
-{ 0.000000f, -0.955423f, -0.295242f },
-{ 0.000000f, -1.000000f, 0.000000f },
-{ 0.262866f, -0.951056f, -0.162460f },
-{ 0.000000f, -0.850651f, 0.525731f },
-{ 0.000000f, -0.955423f, 0.295242f },
-{ 0.238856f, -0.864188f, 0.442863f },
-{ 0.262866f, -0.951056f, 0.162460f },
-{ 0.500000f, -0.809017f, 0.309017f },
-{ 0.716567f, -0.681718f, 0.147621f },
-{ 0.525731f, -0.850651f, 0.000000f },
-{ -0.238856f, -0.864188f, -0.442863f },
-{ -0.500000f, -0.809017f, -0.309017f },
-{ -0.262866f, -0.951056f, -0.162460f },
-{ -0.850651f, -0.525731f, 0.000000f },
-{ -0.716567f, -0.681718f, -0.147621f },
-{ -0.716567f, -0.681718f, 0.147621f },
-{ -0.525731f, -0.850651f, 0.000000f },
-{ -0.500000f, -0.809017f, 0.309017f },
-{ -0.238856f, -0.864188f, 0.442863f },
-{ -0.262866f, -0.951056f, 0.162460f },
-{ -0.864188f, -0.442863f, 0.238856f },
-{ -0.809017f, -0.309017f, 0.500000f },
-{ -0.688191f, -0.587785f, 0.425325f },
-{ -0.681718f, -0.147621f, 0.716567f },
-{ -0.442863f, -0.238856f, 0.864188f },
-{ -0.587785f, -0.425325f, 0.688191f },
-{ -0.309017f, -0.500000f, 0.809017f },
-{ -0.147621f, -0.716567f, 0.681718f },
-{ -0.425325f, -0.688191f, 0.587785f },
-{ -0.162460f, -0.262866f, 0.951056f },
-{ 0.442863f, -0.238856f, 0.864188f },
-{ 0.162460f, -0.262866f, 0.951056f },
-{ 0.309017f, -0.500000f, 0.809017f },
-{ 0.147621f, -0.716567f, 0.681718f },
-{ 0.000000f, -0.525731f, 0.850651f },
-{ 0.425325f, -0.688191f, 0.587785f },
-{ 0.587785f, -0.425325f, 0.688191f },
-{ 0.688191f, -0.587785f, 0.425325f },
-{ -0.955423f, 0.295242f, 0.000000f },
-{ -0.951056f, 0.162460f, 0.262866f },
-{ -1.000000f, 0.000000f, 0.000000f },
-{ -0.850651f, 0.000000f, 0.525731f },
-{ -0.955423f, -0.295242f, 0.000000f },
-{ -0.951056f, -0.162460f, 0.262866f },
-{ -0.864188f, 0.442863f, -0.238856f },
-{ -0.951056f, 0.162460f, -0.262866f },
-{ -0.809017f, 0.309017f, -0.500000f },
-{ -0.864188f, -0.442863f, -0.238856f },
-{ -0.951056f, -0.162460f, -0.262866f },
-{ -0.809017f, -0.309017f, -0.500000f },
-{ -0.681718f, 0.147621f, -0.716567f },
-{ -0.681718f, -0.147621f, -0.716567f },
-{ -0.850651f, 0.000000f, -0.525731f },
-{ -0.688191f, 0.587785f, -0.425325f },
-{ -0.587785f, 0.425325f, -0.688191f },
-{ -0.425325f, 0.688191f, -0.587785f },
-{ -0.425325f, -0.688191f, -0.587785f },
-{ -0.587785f, -0.425325f, -0.688191f },
-{ -0.688191f, -0.587785f, -0.425325f }
-};
-
-#endif // !! include guard
diff --git a/3rdparty/assimp/code/MD3FileData.h b/3rdparty/assimp/code/MD3FileData.h
deleted file mode 100644
index 0c092bcb..00000000
--- a/3rdparty/assimp/code/MD3FileData.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Md3FileData.h
- *
- * @brief Defines helper data structures for importing MD3 files.
- * http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
- */
-#ifndef AI_MD3FILEHELPER_H_INC
-#define AI_MD3FILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-#include "./../include/Compiler/pushpack1.h"
-
-namespace Assimp {
-namespace MD3 {
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MD3_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP3")
-#define AI_MD3_MAGIC_NUMBER_LE AI_MAKE_MAGIC("3PDI")
-
-// common limitations
-#define AI_MD3_VERSION 15
-#define AI_MD3_MAXQPATH 64
-#define AI_MD3_MAXFRAME 16
-#define AI_MD3_MAX_FRAMES 1024
-#define AI_MD3_MAX_TAGS 16
-#define AI_MD3_MAX_SURFACES 32
-#define AI_MD3_MAX_SHADERS 256
-#define AI_MD3_MAX_VERTS 4096
-#define AI_MD3_MAX_TRIANGLES 8192
-
-// master scale factor for all vertices in a MD3 model
-#define AI_MD3_XYZ_SCALE (1.0f/64.0f)
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the MD3 main header
- */
-struct Header
-{
- //! magic number
- uint32_t IDENT;
-
- //! file format version
- uint32_t VERSION;
-
- //! original name in .pak archive
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! unknown
- int32_t FLAGS;
-
- //! number of frames in the file
- uint32_t NUM_FRAMES;
-
- //! number of tags in the file
- uint32_t NUM_TAGS;
-
- //! number of surfaces in the file
- uint32_t NUM_SURFACES;
-
- //! number of skins in the file
- uint32_t NUM_SKINS;
-
- //! offset of the first frame
- uint32_t OFS_FRAMES;
-
- //! offset of the first tag
- uint32_t OFS_TAGS;
-
- //! offset of the first surface
- uint32_t OFS_SURFACES;
-
- //! end of file
- uint32_t OFS_EOF;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the frame header
- */
-struct Frame
-{
- //! minimum bounds
- aiVector3D min;
-
- //! maximum bounds
- aiVector3D max;
-
- //! local origin for this frame
- aiVector3D origin;
-
- //! radius of bounding sphere
- float radius;
-
- //! name of frame
- char name[ AI_MD3_MAXFRAME ];
-
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the tag header
- */
-struct Tag
-{
- //! name of the tag
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! Local tag origin and orientation
- aiVector3D origin;
- float orientation[3][3];
-
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the surface header
- */
-struct Surface
-{
- //! magic number
- int32_t IDENT;
-
- //! original name of the surface
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! unknown
- int32_t FLAGS;
-
- //! number of frames in the surface
- uint32_t NUM_FRAMES;
-
- //! number of shaders in the surface
- uint32_t NUM_SHADER;
-
- //! number of vertices in the surface
- uint32_t NUM_VERTICES;
-
- //! number of triangles in the surface
- uint32_t NUM_TRIANGLES;
-
-
- //! offset to the triangle data
- uint32_t OFS_TRIANGLES;
-
- //! offset to the shader data
- uint32_t OFS_SHADERS;
-
- //! offset to the texture coordinate data
- uint32_t OFS_ST;
-
- //! offset to the vertex/normal data
- uint32_t OFS_XYZNORMAL;
-
- //! offset to the end of the Surface object
- int32_t OFS_END;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a shader defined in there
- */
-struct Shader
-{
- //! filename of the shader
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! index of the shader
- uint32_t SHADER_INDEX;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a triangle
- */
-struct Triangle
-{
- //! triangle indices
- uint32_t INDEXES[3];
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for an UV coord
- */
-struct TexCoord
-{
- //! UV coordinates
- float U,V;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a vertex
- */
-struct Vertex
-{
- //! X/Y/Z coordinates
- int16_t X,Y,Z;
-
- //! encoded normal vector
- uint16_t NORMAL;
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-// -------------------------------------------------------------------------------
-/** @brief Unpack a Q3 16 bit vector to its full float3 representation
- *
- * @param p_iNormal Input normal vector in latitude/longitude form
- * @param p_afOut Pointer to an array of three floats to receive the result
- *
- * @note This has been taken from q3 source (misc_model.c)
- */
-inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut)
-{
- float lat = (float)(( p_iNormal >> 8u ) & 0xff);
- float lng = (float)(( p_iNormal & 0xff ));
- lat *= 3.141926f/128.0f;
- lng *= 3.141926f/128.0f;
-
- p_afOut[0] = cosf(lat) * sinf(lng);
- p_afOut[1] = sinf(lat) * sinf(lng);
- p_afOut[2] = cosf(lng);
- return;
-}
-
-
-// -------------------------------------------------------------------------------
-/** @brief Pack a Q3 normal into 16bit latitute/longitude representation
- * @param p_vIn Input vector
- * @param p_iOut Output normal
- *
- * @note This has been taken from q3 source (mathlib.c)
- */
-inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
-{
- // check for singularities
- if ( 0.0f == p_vIn[0] && 0.0f == p_vIn[1] )
- {
- if ( p_vIn[2] > 0.0f )
- {
- ((unsigned char*)&p_iOut)[0] = 0;
- ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 0
- }
- else
- {
- ((unsigned char*)&p_iOut)[0] = 128;
- ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 128
- }
- }
- else
- {
- int a, b;
-
- a = int(57.2957795f * ( atan2f( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
- a &= 0xff;
-
- b = int(57.2957795f * ( acosf( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
- b &= 0xff;
-
- ((unsigned char*)&p_iOut)[0] = b; // longitude
- ((unsigned char*)&p_iOut)[1] = a; // lattitude
- }
-}
-
-}
-}
-
-#endif // !! AI_MD3FILEHELPER_H_INC
-
diff --git a/3rdparty/assimp/code/MD3Loader.cpp b/3rdparty/assimp/code/MD3Loader.cpp
deleted file mode 100644
index 0e37afc5..00000000
--- a/3rdparty/assimp/code/MD3Loader.cpp
+++ /dev/null
@@ -1,1043 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MD3Loader.cpp
- * @brief Implementation of the MD3 importer class
- *
- * Sources:
- * http://www.gamers.org/dEngine/quake3/UQ3S
- * http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
- * http://www.heppler.com/shader/shader/
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-
-#include "MD3Loader.h"
-#include "ByteSwap.h"
-#include "SceneCombiner.h"
-#include "GenericProperty.h"
-#include "RemoveComments.h"
-#include "ParsingUtils.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Convert a Q3 shader blend function to the appropriate enum value
-Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
-{
- if (m == "GL_ONE") {
- return Q3Shader::BLEND_GL_ONE;
- }
- if (m == "GL_ZERO") {
- return Q3Shader::BLEND_GL_ZERO;
- }
- if (m == "GL_SRC_ALPHA") {
- return Q3Shader::BLEND_GL_SRC_ALPHA;
- }
- if (m == "GL_ONE_MINUS_SRC_ALPHA") {
- return Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
- }
- if (m == "GL_ONE_MINUS_DST_COLOR") {
- return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR;
- }
- DefaultLogger::get()->error("Q3Shader: Unknown blend function: " + m);
- return Q3Shader::BLEND_NONE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a Quake 3 shader
-bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* io)
-{
- boost::scoped_ptr<IOStream> file( io->Open( pFile, "rt"));
- if (!file.get())
- return false; // if we can't access the file, don't worry and return
-
- DefaultLogger::get()->info("Loading Quake3 shader file " + pFile);
-
- // read file in memory
- const size_t s = file->FileSize();
- std::vector<char> _buff(s+1);
- file->Read(&_buff[0],s,1);
- _buff[s] = 0;
-
- // remove comments from it (C++ style)
- CommentRemover::RemoveLineComments("//",&_buff[0]);
- const char* buff = &_buff[0];
-
- Q3Shader::ShaderDataBlock* curData = NULL;
- Q3Shader::ShaderMapBlock* curMap = NULL;
-
- // read line per line
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
-
- if (*buff == '{') {
- ++buff;
-
- // append to last section, if any
- if (!curData) {
- DefaultLogger::get()->error("Q3Shader: Unexpected shader section token \'{\'");
- return true; // still no failure, the file is there
- }
-
- // read this data section
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
- if (*buff == '{') {
- ++buff;
- // add new map section
- curData->maps.push_back(Q3Shader::ShaderMapBlock());
- curMap = &curData->maps.back();
-
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
- // 'map' - Specifies texture file name
- if (TokenMatchI(buff,"map",3) || TokenMatchI(buff,"clampmap",8)) {
- curMap->name = GetNextToken(buff);
- }
- // 'blendfunc' - Alpha blending mode
- else if (TokenMatchI(buff,"blendfunc",9)) {
- const std::string blend_src = GetNextToken(buff);
- if (blend_src == "add") {
- curMap->blend_src = Q3Shader::BLEND_GL_ONE;
- curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
- }
- else if (blend_src == "filter") {
- curMap->blend_src = Q3Shader::BLEND_GL_DST_COLOR;
- curMap->blend_dest = Q3Shader::BLEND_GL_ZERO;
- }
- else if (blend_src == "blend") {
- curMap->blend_src = Q3Shader::BLEND_GL_SRC_ALPHA;
- curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
- }
- else {
- curMap->blend_src = StringToBlendFunc(blend_src);
- curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
- }
- }
- // 'alphafunc' - Alpha testing mode
- else if (TokenMatchI(buff,"alphafunc",9)) {
- const std::string at = GetNextToken(buff);
- if (at == "GT0") {
- curMap->alpha_test = Q3Shader::AT_GT0;
- }
- else if (at == "LT128") {
- curMap->alpha_test = Q3Shader::AT_LT128;
- }
- else if (at == "GE128") {
- curMap->alpha_test = Q3Shader::AT_GE128;
- }
- }
- else if (*buff == '}') {
- ++buff;
- // close this map section
- curMap = NULL;
- break;
- }
- }
-
- }
- else if (*buff == '}') {
- ++buff;
- curData = NULL;
- break;
- }
-
- // 'cull' specifies culling behaviour for the model
- else if (TokenMatchI(buff,"cull",4)) {
- SkipSpaces(&buff);
- if (!ASSIMP_strincmp(buff,"back",4)) {
- curData->cull = Q3Shader::CULL_CCW;
- }
- else if (!ASSIMP_strincmp(buff,"front",5)) {
- curData->cull = Q3Shader::CULL_CW;
- }
- else if (!ASSIMP_strincmp(buff,"none",4) || !ASSIMP_strincmp(buff,"disable",7)) {
- curData->cull = Q3Shader::CULL_NONE;
- }
- else DefaultLogger::get()->error("Q3Shader: Unrecognized cull mode");
- }
- }
- }
-
- else {
- // add new section
- fill.blocks.push_back(Q3Shader::ShaderDataBlock());
- curData = &fill.blocks.back();
-
- // get the name of this section
- curData->name = GetNextToken(buff);
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a Quake 3 skin
-bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
-{
- boost::scoped_ptr<IOStream> file( io->Open( pFile, "rt"));
- if (!file.get())
- return false; // if we can't access the file, don't worry and return
-
- DefaultLogger::get()->info("Loading Quake3 skin file " + pFile);
-
- // read file in memory
- const size_t s = file->FileSize();
- std::vector<char> _buff(s+1);const char* buff = &_buff[0];
- file->Read(&_buff[0],s,1);
- _buff[s] = 0;
-
- // remove commas
- std::replace(_buff.begin(),_buff.end(),',',' ');
-
- // read token by token and fill output table
- for (;*buff;) {
- SkipSpacesAndLineEnd(&buff);
-
- // get first identifier
- std::string ss = GetNextToken(buff);
-
- // ignore tokens starting with tag_
- if (!::strncmp(&ss[0],"tag_",std::min((size_t)4, ss.length())))
- continue;
-
- fill.textures.push_back(SkinData::TextureEntry());
- SkinData::TextureEntry& s = fill.textures.back();
-
- s.first = ss;
- s.second = GetNextToken(buff);
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert Q3Shader to material
-void Q3Shader::ConvertShaderToMaterial(MaterialHelper* out, const ShaderDataBlock& shader)
-{
- ai_assert(NULL != out);
-
- /* IMPORTANT: This is not a real conversion. Actually we're just guessing and
- * hacking around to build an aiMaterial that looks nearly equal to the
- * original Quake 3 shader. We're missing some important features like
- * animatable material properties in our material system, but at least
- * multiple textures should be handled correctly.
- */
-
- // Two-sided material?
- if (shader.cull == Q3Shader::CULL_NONE) {
- const int twosided = 1;
- out->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
- }
-
- unsigned int cur_emissive = 0, cur_diffuse = 0, cur_lm =0;
-
- // Iterate through all textures
- for (std::list< Q3Shader::ShaderMapBlock >::const_iterator it = shader.maps.begin(); it != shader.maps.end();++it) {
-
- // CONVERSION BEHAVIOUR:
- //
- //
- // If the texture is additive
- // - if it is the first texture, assume additive blending for the whole material
- // - otherwise register it as emissive texture.
- //
- // If the texture is using standard blend (or if the blend mode is unknown)
- // - if first texture: assume default blending for material
- // - in any case: set it as diffuse texture
- //
- // If the texture is using 'filter' blending
- // - take as lightmap
- //
- // Textures with alpha funcs
- // - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
- aiString s((*it).name);
- aiTextureType type; unsigned int index;
-
- if ((*it).blend_src == Q3Shader::BLEND_GL_ONE && (*it).blend_dest == Q3Shader::BLEND_GL_ONE) {
- if (it == shader.maps.begin()) {
- const int additive = aiBlendMode_Additive;
- out->AddProperty(&additive,1,AI_MATKEY_BLEND_FUNC);
-
- index = cur_diffuse++;
- type = aiTextureType_DIFFUSE;
- }
- else {
- index = cur_emissive++;
- type = aiTextureType_EMISSIVE;
- }
- }
- else if ((*it).blend_src == Q3Shader::BLEND_GL_DST_COLOR && (*it).blend_dest == Q3Shader::BLEND_GL_ZERO) {
- index = cur_lm++;
- type = aiTextureType_LIGHTMAP;
- }
- else {
- const int blend = aiBlendMode_Default;
- out->AddProperty(&blend,1,AI_MATKEY_BLEND_FUNC);
-
- index = cur_diffuse++;
- type = aiTextureType_DIFFUSE;
- }
-
- // setup texture
- out->AddProperty(&s,AI_MATKEY_TEXTURE(type,index));
-
- // setup texture flags
- const int use_alpha = ((*it).alpha_test != Q3Shader::AT_NONE ? aiTextureFlags_UseAlpha : aiTextureFlags_IgnoreAlpha);
- out->AddProperty(&use_alpha,1,AI_MATKEY_TEXFLAGS(type,index));
- }
- // If at least one emissive texture was set, set the emissive base color to 1 to ensure
- // the texture is actually displayed.
- if (0 != cur_emissive) {
- aiColor3D one(1.f,1.f,1.f);
- out->AddProperty(&one,1,AI_MATKEY_COLOR_EMISSIVE);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD3Importer::MD3Importer()
-: configFrameID (0)
-, configHandleMP (true)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD3Importer::~MD3Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "md3")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MD3_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MD3Importer::ValidateHeaderOffsets()
-{
- // Check magic number
- if (pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
- pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
- throw DeadlyImportError( "Invalid MD3 file: Magic bytes not found");
-
- // Check file format version
- if (pcHeader->VERSION > 15)
- DefaultLogger::get()->warn( "Unsupported MD3 file version. Continuing happily ...");
-
- // Check some offset values whether they are valid
- if (!pcHeader->NUM_SURFACES)
- throw DeadlyImportError( "Invalid md3 file: NUM_SURFACES is 0");
-
- if (pcHeader->OFS_FRAMES >= fileSize || pcHeader->OFS_SURFACES >= fileSize ||
- pcHeader->OFS_EOF > fileSize) {
- throw DeadlyImportError("Invalid MD3 header: some offsets are outside the file");
- }
-
- if (pcHeader->NUM_FRAMES <= configFrameID )
- throw DeadlyImportError("The requested frame is not existing the file");
-}
-
-// ------------------------------------------------------------------------------------------------
-void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
-{
- // Calculate the relative offset of the surface
- const int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer);
-
- // Check whether all data chunks are inside the valid range
- if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > fileSize ||
- pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize ||
- pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize ||
- pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize) {
-
- throw DeadlyImportError("Invalid MD3 surface header: some offsets are outside the file");
- }
-
- // Check whether all requirements for Q3 files are met. We don't
- // care, but probably someone does.
- if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) {
- DefaultLogger::get()->warn("MD3: Quake III triangle limit exceeded");
- }
-
- if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) {
- DefaultLogger::get()->warn("MD3: Quake III shader limit exceeded");
- }
-
- if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) {
- DefaultLogger::get()->warn("MD3: Quake III vertex limit exceeded");
- }
-
- if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) {
- DefaultLogger::get()->warn("MD3: Quake III frame limit exceeded");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void MD3Importer::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("md3");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MD3Importer::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_KEYFRAME,0xffffffff);
- if (0xffffffff == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART
- configHandleMP = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART,1));
-
- // AI_CONFIG_IMPORT_MD3_SKIN_NAME
- configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME,"default"));
-
- // AI_CONFIG_IMPORT_MD3_SHADER_SRC
- configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC,""));
-
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to read the skin for a MD3 file
-void MD3Importer::ReadSkin(Q3Shader::SkinData& fill) const
-{
- // skip any postfixes (e.g. lower_1.md3)
- std::string::size_type s = filename.find_last_of('_');
- if (s == std::string::npos) {
- s = filename.find_last_of('.');
- }
- ai_assert(s != std::string::npos);
-
- const std::string skin_file = path + filename.substr(0,s) + "_" + configSkinFile + ".skin";
- Q3Shader::LoadSkin(fill,skin_file,mIOHandler);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to read the shader for a MD3 file
-void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
-{
- // Determine Q3 model name from given path
- std::string::size_type s = path.find_last_of("\\/",path.length()-2);
- const std::string model_file = path.substr(s+1,path.length()-(s+2));
-
- // If no specific dir or file is given, use our default search behaviour
- if (!configShaderFile.length()) {
- if (!Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + model_file + ".shader",mIOHandler)) {
- Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + filename + ".shader",mIOHandler);
- }
- }
- else {
- // If the given string specifies a file, load this file.
- // Otherwise it's a directory.
- std::string::size_type st = configShaderFile.find_last_of('.');
- if (st == std::string::npos) {
-
- if (!Q3Shader::LoadShader(fill,configShaderFile + model_file + ".shader",mIOHandler)) {
- Q3Shader::LoadShader(fill,configShaderFile + filename + ".shader",mIOHandler);
- }
- }
- else {
- Q3Shader::LoadShader(fill,configShaderFile,mIOHandler);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tiny helper to remove a single node from its parent' list
-void RemoveSingleNodeFromList(aiNode* nd)
-{
- if (!nd || nd->mNumChildren || !nd->mParent)return;
- aiNode* par = nd->mParent;
- for (unsigned int i = 0; i < par->mNumChildren;++i) {
- if (par->mChildren[i] == nd) {
- --par->mNumChildren;
- for (;i < par->mNumChildren;++i) {
- par->mChildren[i] = par->mChildren[i+1];
- }
- delete nd;
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a multi-part Q3 player model
-bool MD3Importer::ReadMultipartFile()
-{
- // check whether the file name contains a common postfix, e.g lower_2.md3
- std::string::size_type s = filename.find_last_of('_'), t = filename.find_last_of('.');
- ai_assert(t != std::string::npos);
- if (s == std::string::npos)
- s = t;
-
- const std::string mod_filename = filename.substr(0,s);
- const std::string suffix = filename.substr(s,t-s);
-
- if (mod_filename == "lower" || mod_filename == "upper" || mod_filename == "head"){
- const std::string lower = path + "lower" + suffix + ".md3";
- const std::string upper = path + "upper" + suffix + ".md3";
- const std::string head = path + "head" + suffix + ".md3";
-
- aiScene* scene_upper = NULL;
- aiScene* scene_lower = NULL;
- aiScene* scene_head = NULL;
- std::string failure;
-
- aiNode* tag_torso, *tag_head;
- std::vector<AttachmentInfo> attach;
-
- DefaultLogger::get()->info("Multi part MD3 player model: lower, upper and head parts are joined");
-
- // ensure we won't try to load ourselves recursively
- BatchLoader::PropertyMap props;
- SetGenericProperty( props.ints, AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART, 0, NULL);
-
- // now read these three files
- BatchLoader batch(mIOHandler);
- const unsigned int _lower = batch.AddLoadRequest(lower,0,&props);
- const unsigned int _upper = batch.AddLoadRequest(upper,0,&props);
- const unsigned int _head = batch.AddLoadRequest(head,0,&props);
- batch.LoadAll();
-
- // now construct a dummy scene to place these three parts in
- aiScene* master = new aiScene();
- aiNode* nd = master->mRootNode = new aiNode();
- nd->mName.Set("<MD3_Player>");
-
- // ... and get them. We need all of them.
- scene_lower = batch.GetImport(_lower);
- if (!scene_lower) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, lower.md3 fails to load");
- failure = "lower";
- goto error_cleanup;
- }
-
- scene_upper = batch.GetImport(_upper);
- if (!scene_upper) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, upper.md3 fails to load");
- failure = "upper";
- goto error_cleanup;
- }
-
- scene_head = batch.GetImport(_head);
- if (!scene_head) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, head.md3 fails to load");
- failure = "head";
- goto error_cleanup;
- }
-
- // build attachment infos. search for typical Q3 tags
-
- // original root
- scene_lower->mRootNode->mName.Set("lower");
- attach.push_back(AttachmentInfo(scene_lower, nd));
-
- // tag_torso
- tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
- if (!tag_torso) {
- DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_torso expected");
- goto error_cleanup;
- }
- scene_upper->mRootNode->mName.Set("upper");
- attach.push_back(AttachmentInfo(scene_upper,tag_torso));
-
- // tag_head
- tag_head = scene_upper->mRootNode->FindNode("tag_head");
- if (!tag_head) {
- DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_head expected");
- goto error_cleanup;
- }
- scene_head->mRootNode->mName.Set("head");
- attach.push_back(AttachmentInfo(scene_head,tag_head));
-
- // Remove tag_head and tag_torso from all other model parts ...
- // this ensures (together with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY)
- // that tag_torso/tag_head is also the name of the (unique) output node
- RemoveSingleNodeFromList (scene_upper->mRootNode->FindNode("tag_torso"));
- RemoveSingleNodeFromList (scene_head-> mRootNode->FindNode("tag_head" ));
-
- // Undo the rotations which we applied to the coordinate systems. We're
- // working in global Quake space here
- scene_head->mRootNode->mTransformation = aiMatrix4x4();
- scene_lower->mRootNode->mTransformation = aiMatrix4x4();
- scene_upper->mRootNode->mTransformation = aiMatrix4x4();
-
- // and merge the scenes
- SceneCombiner::MergeScenes(&mScene,master, attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES |
- AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES |
- AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS |
- (!configSpeedFlag ? AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY : 0));
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- mScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- return true;
-
-error_cleanup:
- delete scene_upper;
- delete scene_lower;
- delete scene_head;
- delete master;
-
- if (failure == mod_filename) {
- throw DeadlyImportError("MD3: failure to read multipart host file");
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a MD3 path to a proper value
-void MD3Importer::ConvertPath(const char* texture_name, const char* header_name, std::string& out) const
-{
- // If the MD3's internal path itself and the given path are using
- // the same directory, remove it completely to get right output paths.
- const char* end1 = ::strrchr(header_name,'\\');
- if (!end1)end1 = ::strrchr(header_name,'/');
-
- const char* end2 = ::strrchr(texture_name,'\\');
- if (!end2)end2 = ::strrchr(texture_name,'/');
-
- // HACK: If the paths starts with "models", ignore the
- // next two hierarchy levels, it specifies just the model name.
- // Ignored by Q3, it might be not equal to the real model location.
- if (end2) {
-
- size_t len2;
- const size_t len1 = (size_t)(end1 - header_name);
- if (!ASSIMP_strincmp(texture_name,"models",6) && (texture_name[6] == '/' || texture_name[6] == '\\')) {
- len2 = 6; // ignore the seventh - could be slash or backslash
-
- if (!header_name[0]) {
- // Use the file name only
- out = end2+1;
- return;
- }
- }
- else len2 = std::min (len1, (size_t)(end2 - texture_name ));
- if (!ASSIMP_strincmp(texture_name,header_name,len2)) {
- // Use the file name only
- out = end2+1;
- return;
- }
- }
- // Use the full path
- out = texture_name;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD3Importer::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- mFile = pFile;
- mScene = pScene;
- mIOHandler = pIOHandler;
-
- // get base path and file name
- // todo ... move to PathConverter
- std::string::size_type s = mFile.find_last_of("/\\");
- if (s == std::string::npos) {
- s = 0;
- }
- else ++s;
- filename = mFile.substr(s), path = mFile.substr(0,s);
- for ( std::string::iterator it = filename .begin(); it != filename.end(); ++it)
- *it = tolower( *it);
-
- // Load multi-part model file, if necessary
- if (configHandleMP) {
- if (ReadMultipartFile())
- return;
- }
-
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MD3 file " + pFile + ".");
-
- // Check whether the md3 file is large enough to contain the header
- fileSize = (unsigned int)file->FileSize();
- if ( fileSize < sizeof(MD3::Header))
- throw DeadlyImportError( "MD3 File is too small.");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<unsigned char> mBuffer2 (fileSize);
- file->Read( &mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
- pcHeader = (BE_NCONST MD3::Header*)mBuffer;
-
- // Ensure correct endianess
-#ifdef AI_BUILD_BIG_ENDIAN
-
- AI_SWAP4(pcHeader->VERSION);
- AI_SWAP4(pcHeader->FLAGS);
- AI_SWAP4(pcHeader->IDENT);
- AI_SWAP4(pcHeader->NUM_FRAMES);
- AI_SWAP4(pcHeader->NUM_SKINS);
- AI_SWAP4(pcHeader->NUM_SURFACES);
- AI_SWAP4(pcHeader->NUM_TAGS);
- AI_SWAP4(pcHeader->OFS_EOF);
- AI_SWAP4(pcHeader->OFS_FRAMES);
- AI_SWAP4(pcHeader->OFS_SURFACES);
- AI_SWAP4(pcHeader->OFS_TAGS);
-
-#endif
-
- // Validate the file header
- ValidateHeaderOffsets();
-
- // Navigate to the list of surfaces
- BE_NCONST MD3::Surface* pcSurfaces = (BE_NCONST MD3::Surface*)(mBuffer + pcHeader->OFS_SURFACES);
-
- // Navigate to the list of tags
- BE_NCONST MD3::Tag* pcTags = (BE_NCONST MD3::Tag*)(mBuffer + pcHeader->OFS_TAGS);
-
- // Allocate output storage
- pScene->mNumMeshes = pcHeader->NUM_SURFACES;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- pScene->mNumMaterials = pcHeader->NUM_SURFACES;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
-
- // Set arrays to zero to ensue proper destruction if an exception is raised
- ::memset(pScene->mMeshes,0,pScene->mNumMeshes*sizeof(aiMesh*));
- ::memset(pScene->mMaterials,0,pScene->mNumMaterials*sizeof(aiMaterial*));
-
- // Now read possible skins from .skin file
- Q3Shader::SkinData skins;
- ReadSkin(skins);
-
- // And check whether we can locate a shader file for this model
- Q3Shader::ShaderData shaders;
- ReadShader(shaders);
-
- // Adjust all texture paths in the shader
- const char* header_name = pcHeader->NAME;
- if (shaders.blocks.size()) {
- for (std::list< Q3Shader::ShaderDataBlock >::iterator dit = shaders.blocks.begin(); dit != shaders.blocks.end(); ++dit) {
- ConvertPath((*dit).name.c_str(),header_name,(*dit).name);
-
- for (std::list< Q3Shader::ShaderMapBlock >::iterator mit = (*dit).maps.begin(); mit != (*dit).maps.end(); ++mit) {
- ConvertPath((*mit).name.c_str(),header_name,(*mit).name);
- }
- }
- }
-
- // Read all surfaces from the file
- unsigned int iNum = pcHeader->NUM_SURFACES;
- unsigned int iNumMaterials = 0;
- while (iNum-- > 0) {
-
- // Ensure correct endianess
-#ifdef AI_BUILD_BIG_ENDIAN
-
- AI_SWAP4(pcSurfaces->FLAGS);
- AI_SWAP4(pcSurfaces->IDENT);
- AI_SWAP4(pcSurfaces->NUM_FRAMES);
- AI_SWAP4(pcSurfaces->NUM_SHADER);
- AI_SWAP4(pcSurfaces->NUM_TRIANGLES);
- AI_SWAP4(pcSurfaces->NUM_VERTICES);
- AI_SWAP4(pcSurfaces->OFS_END);
- AI_SWAP4(pcSurfaces->OFS_SHADERS);
- AI_SWAP4(pcSurfaces->OFS_ST);
- AI_SWAP4(pcSurfaces->OFS_TRIANGLES);
- AI_SWAP4(pcSurfaces->OFS_XYZNORMAL);
-
-#endif
-
- // Validate the surface header
- ValidateSurfaceHeaderOffsets(pcSurfaces);
-
- // Navigate to the vertex list of the surface
- BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
-
- // Navigate to the triangle list of the surface
- BE_NCONST MD3::Triangle* pcTriangles = (BE_NCONST MD3::Triangle*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
-
- // Navigate to the texture coordinate list of the surface
- BE_NCONST MD3::TexCoord* pcUVs = (BE_NCONST MD3::TexCoord*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_ST);
-
- // Navigate to the shader list of the surface
- BE_NCONST MD3::Shader* pcShaders = (BE_NCONST MD3::Shader*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
-
- // If the submesh is empty ignore it
- if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
- {
- pcSurfaces = (BE_NCONST MD3::Surface*)(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_END);
- pScene->mNumMeshes--;
- continue;
- }
-
- // Allocate output mesh
- pScene->mMeshes[iNum] = new aiMesh();
- aiMesh* pcMesh = pScene->mMeshes[iNum];
-
- std::string _texture_name;
- const char* texture_name = NULL;
-
- // Check whether we have a texture record for this surface in the .skin file
- std::list< Q3Shader::SkinData::TextureEntry >::iterator it = std::find(
- skins.textures.begin(), skins.textures.end(), pcSurfaces->NAME );
-
- if (it != skins.textures.end()) {
- texture_name = &*( _texture_name = (*it).second).begin();
- DefaultLogger::get()->debug("MD3: Assigning skin texture " + (*it).second + " to surface " + pcSurfaces->NAME);
- (*it).resolved = true; // mark entry as resolved
- }
-
- // Get the first shader (= texture?) assigned to the surface
- if (!texture_name && pcSurfaces->NUM_SHADER) {
- texture_name = pcShaders->NAME;
- }
-
- std::string convertedPath;
- if (texture_name) {
- ConvertPath(texture_name,header_name,convertedPath);
- }
-
- const Q3Shader::ShaderDataBlock* shader = NULL;
-
- // Now search the current shader for a record with this name (
- // excluding texture file extension)
- if (shaders.blocks.size()) {
-
- std::string::size_type s = convertedPath.find_last_of('.');
- if (s == std::string::npos)
- s = convertedPath.length();
-
- const std::string without_ext = convertedPath.substr(0,s);
- std::list< Q3Shader::ShaderDataBlock >::const_iterator dit = std::find(shaders.blocks.begin(),shaders.blocks.end(),without_ext);
- if (dit != shaders.blocks.end()) {
- // Hurra, wir haben einen. Tolle Sache.
- shader = &*dit;
- DefaultLogger::get()->info("Found shader record for " +without_ext );
- }
- else DefaultLogger::get()->warn("Unable to find shader record for " +without_ext );
- }
-
- MaterialHelper* pcHelper = new MaterialHelper();
-
- const int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // Add a small ambient color value - Quake 3 seems to have one
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- // use surface name + skin_name as material name
- aiString name;
- name.Set("MD3_[" + configSkinFile + "][" + pcSurfaces->NAME + "]");
- pcHelper->AddProperty(&name,AI_MATKEY_NAME);
-
- if (!shader) {
- // Setup dummy texture file name to ensure UV coordinates are kept during postprocessing
- aiString szString;
- if (convertedPath.length()) {
- szString.Set(convertedPath);
- }
- else {
- DefaultLogger::get()->warn("Texture file name has zero length. Using default name");
- szString.Set("dummy_texture.bmp");
- }
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // prevent transparency by default
- int no_alpha = aiTextureFlags_IgnoreAlpha;
- pcHelper->AddProperty(&no_alpha,1,AI_MATKEY_TEXFLAGS_DIFFUSE(0));
- }
- else {
- Q3Shader::ConvertShaderToMaterial(pcHelper,*shader);
- }
-
- pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
- pcMesh->mMaterialIndex = iNumMaterials++;
-
- // Ensure correct endianess
-#ifdef AI_BUILD_BIG_ENDIAN
-
- for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i) {
- AI_SWAP2( pcVertices[i].NORMAL );
- AI_SWAP2( pcVertices[i].X );
- AI_SWAP2( pcVertices[i].Y );
- AI_SWAP2( pcVertices[i].Z );
-
- AI_SWAP4( pcUVs[i].U );
- AI_SWAP4( pcUVs[i].U );
- }
- for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i) {
- AI_SWAP4(pcTriangles[i].INDEXES[0]);
- AI_SWAP4(pcTriangles[i].INDEXES[1]);
- AI_SWAP4(pcTriangles[i].INDEXES[2]);
- }
-
-#endif
-
- // Fill mesh information
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pcMesh->mNumVertices = pcSurfaces->NUM_TRIANGLES*3;
- pcMesh->mNumFaces = pcSurfaces->NUM_TRIANGLES;
- pcMesh->mFaces = new aiFace[pcSurfaces->NUM_TRIANGLES];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // Fill in all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int)pcSurfaces->NUM_TRIANGLES;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- //unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- pcMesh->mFaces[i].mIndices[c] = iCurrent;
-
- // Read vertices
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
- vec.y = pcVertices[ pcTriangles->INDEXES[c]].Y*AI_MD3_XYZ_SCALE;
- vec.z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
-
- // Convert the normal vector to uncompressed float3 format
- aiVector3D& nor = pcMesh->mNormals[iCurrent];
- LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,(float*)&nor);
-
- // Read texture coordinates
- pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
- pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[ pcTriangles->INDEXES[c]].V;
- }
- // Flip face order if necessary
- if (!shader || shader->cull == Q3Shader::CULL_CW) {
- std::swap(pcMesh->mFaces[i].mIndices[2],pcMesh->mFaces[i].mIndices[1]);
- }
- pcTriangles++;
- }
-
- // Go to the next surface
- pcSurfaces = (BE_NCONST MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
- }
-
- // For debugging purposes: check whether we found matches for all entries in the skins file
- if (!DefaultLogger::isNullLogger()) {
- for (std::list< Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin();it != skins.textures.end(); ++it) {
- if (!(*it).resolved) {
- DefaultLogger::get()->error("MD3: Failed to match skin " + (*it).first + " to surface " + (*it).second);
- }
- }
- }
-
- if (!pScene->mNumMeshes)
- throw DeadlyImportError( "MD3: File contains no valid mesh");
- pScene->mNumMaterials = iNumMaterials;
-
- // Now we need to generate an empty node graph
- pScene->mRootNode = new aiNode("<MD3Root>");
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- // Attach tiny children for all tags
- if (pcHeader->NUM_TAGS) {
- pScene->mRootNode->mNumChildren = pcHeader->NUM_TAGS;
- pScene->mRootNode->mChildren = new aiNode*[pcHeader->NUM_TAGS];
-
- for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
-
- aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
- nd->mName.Set((const char*)pcTags->NAME);
- nd->mParent = pScene->mRootNode;
-
- AI_SWAP4(pcTags->origin.x);
- AI_SWAP4(pcTags->origin.y);
- AI_SWAP4(pcTags->origin.z);
-
- // Copy local origin, again flip z,y
- nd->mTransformation.a4 = pcTags->origin.x;
- nd->mTransformation.b4 = pcTags->origin.y;
- nd->mTransformation.c4 = pcTags->origin.z;
-
- // Copy rest of transformation (need to transpose to match row-order matrix)
- for (unsigned int a = 0; a < 3;++a) {
- for (unsigned int m = 0; m < 3;++m) {
- nd->mTransformation[m][a] = pcTags->orientation[a][m];
- AI_SWAP4(nd->mTransformation[m][a]);
- }
- }
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER
diff --git a/3rdparty/assimp/code/MD3Loader.h b/3rdparty/assimp/code/MD3Loader.h
deleted file mode 100644
index e4a65a52..00000000
--- a/3rdparty/assimp/code/MD3Loader.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Md3Loader.h
- * @brief Declaration of the .MD3 importer class.
- */
-#ifndef AI_MD3LOADER_H_INCLUDED
-#define AI_MD3LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "ByteSwap.h"
-
-#include "../include/aiTypes.h"
-
-#include "MD3FileData.h"
-namespace Assimp {
-class MaterialHelper;
-
-using namespace MD3;
-namespace Q3Shader {
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold the data of a .skin file
- */
-struct SkinData
-{
- //! A single entryin texture list
- struct TextureEntry : public std::pair<std::string,std::string>
- {
- // did we resolve this texture entry?
- bool resolved;
-
- // for std::find()
- bool operator == (const std::string& f) const {
- return f == first;
- }
- };
-
- //! List of textures
- std::list<TextureEntry> textures;
-
- // rest is ignored for the moment
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies cull modi for Quake shader files.
- */
-enum ShaderCullMode
-{
- CULL_NONE,
- CULL_CW,
- CULL_CCW
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies alpha blend modi (src + dest) for Quake shader files
- */
-enum BlendFunc
-{
- BLEND_NONE,
- BLEND_GL_ONE,
- BLEND_GL_ZERO,
- BLEND_GL_DST_COLOR,
- BLEND_GL_ONE_MINUS_DST_COLOR,
- BLEND_GL_SRC_ALPHA,
- BLEND_GL_ONE_MINUS_SRC_ALPHA
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies alpha test modi for Quake texture maps
- */
-enum AlphaTestFunc
-{
- AT_NONE,
- AT_GT0,
- AT_LT128,
- AT_GE128
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold a .shader map data block
- */
-struct ShaderMapBlock
-{
- ShaderMapBlock()
- : blend_src (BLEND_NONE)
- , blend_dest (BLEND_NONE)
- , alpha_test (AT_NONE)
- {}
-
- //! Name of referenced map
- std::string name;
-
- //! Blend and alpha test settings for texture
- BlendFunc blend_src,blend_dest;
- AlphaTestFunc alpha_test;
-
-
- //! For std::find()
- bool operator== (const std::string& o) const {
- return !ASSIMP_stricmp(o,name);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold a .shader data block
- */
-struct ShaderDataBlock
-{
- ShaderDataBlock()
- : cull (CULL_CW)
- {}
-
- //! Name of referenced data element
- std::string name;
-
- //! Cull mode for the element
- ShaderCullMode cull;
-
- //! Maps defined in the shader
- std::list<ShaderMapBlock> maps;
-
-
- //! For std::find()
- bool operator== (const std::string& o) const {
- return !ASSIMP_stricmp(o,name);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold the data of a .shader file
- */
-struct ShaderData
-{
- //! Shader data blocks
- std::list<ShaderDataBlock> blocks;
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Load a shader file
- *
- * Generally, parsing is error tolerant. There's no failure.
- * @param fill Receives output data
- * @param file File to be read.
- * @param io IOSystem to be used for reading
- * @return false if file is not accessible
- */
-bool LoadShader(ShaderData& fill, const std::string& file,IOSystem* io);
-
-
-// ---------------------------------------------------------------------------
-/** @brief Convert a Q3Shader to an aiMaterial
- *
- * @param[out] out Material structure to be filled.
- * @param[in] shader Input shader
- */
-void ConvertShaderToMaterial(MaterialHelper* out, const ShaderDataBlock& shader);
-
-// ---------------------------------------------------------------------------
-/** @brief Load a skin file
- *
- * Generally, parsing is error tolerant. There's no failure.
- * @param fill Receives output data
- * @param file File to be read.
- * @param io IOSystem to be used for reading
- * @return false if file is not accessible
- */
-bool LoadSkin(SkinData& fill, const std::string& file,IOSystem* io);
-
-} // ! namespace Q3SHader
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load MD3 files
-*/
-class MD3Importer : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- MD3Importer();
-
- /** Destructor, private as well */
- ~MD3Importer();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Validate offsets in the header
- */
- void ValidateHeaderOffsets();
- void ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurfHeader);
-
- // -------------------------------------------------------------------
- /** Read a Q3 multipart file
- * @return true if multi part has been processed
- */
- bool ReadMultipartFile();
-
- // -------------------------------------------------------------------
- /** Try to read the skin for a MD3 file
- * @param fill Receives output information
- */
- void ReadSkin(Q3Shader::SkinData& fill) const;
-
- // -------------------------------------------------------------------
- /** Try to read the shader for a MD3 file
- * @param fill Receives output information
- */
- void ReadShader(Q3Shader::ShaderData& fill) const;
-
- // -------------------------------------------------------------------
- /** Convert a texture path in a MD3 file to a proper value
- * @param[in] texture_name Path to be converted
- * @param[in] header_path Base path specified in MD3 header
- * @param[out] out Receives the converted output string
- */
- void ConvertPath(const char* texture_name, const char* header_path,
- std::string& out) const;
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Configuration option: process multi-part files */
- bool configHandleMP;
-
- /** Configuration option: name of skin file to be read */
- std::string configSkinFile;
-
- /** Configuration option: name or path of shader */
- std::string configShaderFile;
-
- /** Configuration option: speed flag was set? */
- bool configSpeedFlag;
-
- /** Header of the MD3 file */
- BE_NCONST MD3::Header* pcHeader;
-
- /** File buffer */
- BE_NCONST unsigned char* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Current file name */
- std::string mFile;
-
- /** Current base directory */
- std::string path;
-
- /** Pure file we're currently reading */
- std::string filename;
-
- /** Output scene to be filled */
- aiScene* mScene;
-
- /** IO system to be used to access the data*/
- IOSystem* mIOHandler;
- };
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/MD4FileData.h b/3rdparty/assimp/code/MD4FileData.h
deleted file mode 100644
index 4e97e92b..00000000
--- a/3rdparty/assimp/code/MD4FileData.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines the helper data structures for importing MD4 files */
-#ifndef AI_MD4FILEHELPER_H_INC
-#define AI_MD4FILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack(push,1)
-# define PACK_STRUCT
-#elif defined( __GNUC__ )
-# define PACK_STRUCT __attribute__((packed))
-#else
-# error Compiler not supported
-#endif
-
-
-namespace Assimp
-{
-// http://gongo.quakedev.com/md4.html
-namespace MD4
-{
-
-#define AI_MD4_MAGIC_NUMBER_BE 'IDP4'
-#define AI_MD4_MAGIC_NUMBER_LE '4PDI'
-
-// common limitations
-#define AI_MD4_VERSION 4
-#define AI_MD4_MAXQPATH 64
-#define AI_MD4_MAX_FRAMES 2028
-#define AI_MD4_MAX_SURFACES 32
-#define AI_MD4_MAX_BONES 256
-#define AI_MD4_MAX_VERTS 4096
-#define AI_MD4_MAX_TRIANGLES 8192
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for the MD4 main header
- */
-// ---------------------------------------------------------------------------
-struct Header
-{
- //! magic number
- int32_t magic;
-
- //! file format version
- int32_t version;
-
- //! original name in .pak archive
- unsigned char name[ AI_MD4_MAXQPATH ];
-
- //! number of frames in the file
- int32_t NUM_FRAMES;
-
- //! number of bones in the file
- int32_t NUM_BONES;
-
- //! number of surfaces in the file
- int32_t NUM_SURFACES;
-
- //! offset of the first frame
- int32_t OFS_FRAMES;
-
- //! offset of the first bone
- int32_t OFS_BONES;
-
- //! offset of the first surface
- int32_t OFS_SURFACES;
-
- //! end of file
- int32_t OFS_EOF;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Stores the local transformation matrix of a bone
- */
-// ---------------------------------------------------------------------------
-struct BoneFrame
-{
- float matrix[3][4];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Stores the name / parent index / flag of a node
- */
-// ---------------------------------------------------------------------------
-struct BoneName
-{
- char name[32] ;
- int parent ;
- int flags ;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a surface in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Surface
-{
- int32_t ident;
- char name[64];
- char shader[64];
- int32_t shaderIndex;
- int32_t lodBias;
- int32_t minLod;
- int32_t ofsHeader;
- int32_t numVerts;
- int32_t ofsVerts;
- int32_t numTris;
- int32_t ofsTris;
- int32_t numBoneRefs;
- int32_t ofsBoneRefs;
- int32_t ofsCollapseMap;
- int32_t ofsEnd;
-} PACK_STRUCT;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD4 vertex' weight
- */
-// ---------------------------------------------------------------------------
-struct Weight
-{
- int32_t boneIndex;
- float boneWeight;
- float offset[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a vertex in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Vertex
-{
- float vertex[3];
- float normal[3];
- float texCoords[2];
- int32_t numWeights;
- Weight weights[1];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a triangle in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Triangle
-{
- int32_t indexes[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD4 frame
- */
-// ---------------------------------------------------------------------------
-struct Frame
-{
- float bounds[3][2];
- float localOrigin[3];
- float radius;
- BoneFrame bones[1];
-} PACK_STRUCT;
-
-
-// reset packing to the original value
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack( pop )
-#endif
-#undef PACK_STRUCT
-
-
-};
-};
-
-#endif // !! AI_MD4FILEHELPER_H_INC
diff --git a/3rdparty/assimp/code/MD5Loader.cpp b/3rdparty/assimp/code/MD5Loader.cpp
deleted file mode 100644
index 7c5e4894..00000000
--- a/3rdparty/assimp/code/MD5Loader.cpp
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MD5Loader.cpp
- * @brief Implementation of the MD5 importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-
-// internal headers
-#include "MaterialSystem.h"
-#include "RemoveComments.h"
-#include "MD5Loader.h"
-#include "StringComparison.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-
-using namespace Assimp;
-
-// Minimum weight value. Weights inside [-n ... n] are ignored
-#define AI_MD5_WEIGHT_EPSILON 1e-5f
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD5Importer::MD5Importer()
-: configNoAutoLoad (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD5Importer::~MD5Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
- return true;
- else if (!extension.length() || checkSig) {
- if (!pIOHandler)
- return true;
- const char* tokens[] = {"MD5Version"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of all supported extensions
-void MD5Importer::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("md5anim");
- extensions.insert("md5mesh");
- extensions.insert("md5camera");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void MD5Importer::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
- configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD5Importer::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pIOHandler = _pIOHandler;
- pScene = _pScene;
- bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
-
- // remove the file extension
- std::string::size_type pos = pFile.find_last_of('.');
- mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
-
- const std::string extension = GetExtension(pFile);
- try {
- if (extension == "md5camera") {
- LoadMD5CameraFile();
- }
- else if (configNoAutoLoad || extension == "md5anim") {
- // determine file extension and process just *one* file
- if (extension.length() == 0) {
- /* fixme */
- }
- if (extension == "md5anim") {
- LoadMD5AnimFile();
- }
- else if (extension == "md5mesh") {
- LoadMD5MeshFile();
- }
- }
- else {
- LoadMD5MeshFile();
- LoadMD5AnimFile();
- }
- }
- catch ( std::exception&) {
- // XXX use more idiomatic RAII solution
- UnloadFileFromMemory();
- throw;
- }
-
- // make sure we have at least one file
- if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera)
- throw DeadlyImportError("Failed to read valid contents from this MD5* file");
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- // the output scene wouldn't pass the validation without this flag
- if (!bHadMD5Mesh)
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a file into a memory buffer
-void MD5Importer::LoadFileIntoMemory (IOStream* file)
-{
- ai_assert(NULL != file);
- fileSize = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- pScene = pScene;
- mBuffer = new char[fileSize+1];
- file->Read( (void*)mBuffer, 1, fileSize);
- iLineNumber = 1;
-
- // append a terminal 0
- mBuffer[fileSize] = '\0';
-
- // now remove all line comments from the file
- CommentRemover::RemoveLineComments("//",mBuffer,' ');
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unload the current memory buffer
-void MD5Importer::UnloadFileFromMemory ()
-{
- // delete the file buffer
- delete[] mBuffer;
- mBuffer = NULL;
- fileSize = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build unique vertices
-void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
-{
- std::vector<bool> abHad(meshSrc.mVertices.size(),false);
-
- // allocate enough storage to keep the output structures
- const unsigned int iNewNum = meshSrc.mFaces.size()*3;
- unsigned int iNewIndex = meshSrc.mVertices.size();
- meshSrc.mVertices.resize(iNewNum);
-
- // try to guess how much storage we'll need for new weights
- const float fWeightsPerVert = meshSrc.mWeights.size() / (float)iNewIndex;
- const unsigned int guess = (unsigned int)(fWeightsPerVert*iNewNum);
- meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
-
- for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
- const aiFace& face = *iter;
- for (unsigned int i = 0; i < 3;++i) {
- if (face.mIndices[0] >= meshSrc.mVertices.size())
- throw DeadlyImportError("MD5MESH: Invalid vertex index");
-
- if (abHad[face.mIndices[i]]) {
- // generate a new vertex
- meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
- face.mIndices[i] = iNewIndex++;
- }
- else abHad[face.mIndices[i]] = true;
- }
- // swap face order
- std::swap(face.mIndices[0],face.mIndices[2]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive node graph construction from a MD5MESH
-void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones)
-{
- ai_assert(NULL != piParent && !piParent->mNumChildren);
-
- // First find out how many children we'll have
- for (int i = 0; i < (int)bones.size();++i) {
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- ++piParent->mNumChildren;
- }
- }
- if (piParent->mNumChildren) {
- piParent->mChildren = new aiNode*[piParent->mNumChildren];
- for (int i = 0; i < (int)bones.size();++i) {
- // (avoid infinite recursion)
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- aiNode* pc;
- // setup a new node
- *piParent->mChildren++ = pc = new aiNode();
- pc->mName = aiString(bones[i].mName);
- pc->mParent = piParent;
-
- // get the transformation matrix from rotation and translational components
- aiQuaternion quat;
- MD5::ConvertQuaternion ( bones[i].mRotationQuat, quat );
-
- // FIX to get to Assimp's quaternion conventions
- quat.w *= -1.f;
-
- bones[i].mTransform = aiMatrix4x4 ( quat.GetMatrix());
- bones[i].mTransform.a4 = bones[i].mPositionXYZ.x;
- bones[i].mTransform.b4 = bones[i].mPositionXYZ.y;
- bones[i].mTransform.c4 = bones[i].mPositionXYZ.z;
-
- // store it for later use
- pc->mTransformation = bones[i].mInvTransform = bones[i].mTransform;
- bones[i].mInvTransform.Inverse();
-
- // the transformations for each bone are absolute, so we need to multiply them
- // with the inverse of the absolute matrix of the parent joint
- if (-1 != iParentID) {
- pc->mTransformation = bones[iParentID].mInvTransform * pc->mTransformation;
- }
-
- // add children to this node, too
- AttachChilds_Mesh( i, pc, bones);
- }
- }
- // undo offset computations
- piParent->mChildren -= piParent->mNumChildren;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive node graph construction from a MD5ANIM
-void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims)
-{
- ai_assert(NULL != piParent && !piParent->mNumChildren);
-
- // First find out how many children we'll have
- for (int i = 0; i < (int)bones.size();++i) {
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- ++piParent->mNumChildren;
- }
- }
- if (piParent->mNumChildren) {
- piParent->mChildren = new aiNode*[piParent->mNumChildren];
- for (int i = 0; i < (int)bones.size();++i) {
- // (avoid infinite recursion)
- if (iParentID != i && bones[i].mParentIndex == iParentID)
- {
- aiNode* pc;
- // setup a new node
- *piParent->mChildren++ = pc = new aiNode();
- pc->mName = aiString(bones[i].mName);
- pc->mParent = piParent;
-
- // get the corresponding animation channel and its first frame
- const aiNodeAnim** cur = node_anims;
- while ((**cur).mNodeName != pc->mName)++cur;
-
- aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue,pc->mTransformation);
- pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix()) ;
-
- // add children to this node, too
- AttachChilds_Anim( i, pc, bones,node_anims);
- }
- }
- // undo offset computations
- piParent->mChildren -= piParent->mNumChildren;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a MD5MESH file
-void MD5Importer::LoadMD5MeshFile ()
-{
- std::string pFile = mFile + "md5mesh";
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- DefaultLogger::get()->warn("Failed to read MD5MESH file: " + pFile);
- return;
- }
- bHadMD5Mesh = true;
- LoadFileIntoMemory(file.get());
-
- // now construct a parser and parse the file
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the mesh information from it
- MD5::MD5MeshParser meshParser(parser.mSections);
-
- // create the bone hierarchy - first the root node and dummy nodes for all meshes
- pScene->mRootNode = new aiNode("<MD5_Root>");
- pScene->mRootNode->mNumChildren = 2;
- pScene->mRootNode->mChildren = new aiNode*[2];
-
- // build the hierarchy from the MD5MESH file
- aiNode* pcNode = pScene->mRootNode->mChildren[1] = new aiNode();
- pcNode->mName.Set("<MD5_Hierarchy>");
- pcNode->mParent = pScene->mRootNode;
- AttachChilds_Mesh(-1,pcNode,meshParser.mJoints);
-
- pcNode = pScene->mRootNode->mChildren[0] = new aiNode();
- pcNode->mName.Set("<MD5_Mesh>");
- pcNode->mParent = pScene->mRootNode;
-
-#if 0
- if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
- SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[1]->mChildren[0]);
-#else
- // FIX: MD5 files exported from Blender can have empty meshes
- for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
- if (!(*it).mFaces.empty() && !(*it).mVertices.empty())
- ++pScene->mNumMaterials;
- }
-
- // generate all meshes
- pScene->mNumMeshes = pScene->mNumMaterials;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
-
- // storage for node mesh indices
- pcNode->mNumMeshes = pScene->mNumMeshes;
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- for (unsigned int m = 0; m < pcNode->mNumMeshes;++m)
- pcNode->mMeshes[m] = m;
-
- unsigned int n = 0;
- for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
- MD5::MeshDesc& meshSrc = *it;
- if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty())
- continue;
-
- aiMesh* mesh = pScene->mMeshes[n] = new aiMesh();
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // generate unique vertices in our internal verbose format
- MakeDataUnique(meshSrc);
-
- mesh->mNumVertices = (unsigned int) meshSrc.mVertices.size();
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
-
- // copy texture coordinates
- aiVector3D* pv = mesh->mTextureCoords[0];
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- pv->x = (*iter).mUV.x;
- pv->y = 1.0f-(*iter).mUV.y; // D3D to OpenGL
- pv->z = 0.0f;
- }
-
- // sort all bone weights - per bone
- unsigned int* piCount = new unsigned int[meshParser.mJoints.size()];
- ::memset(piCount,0,sizeof(unsigned int)*meshParser.mJoints.size());
-
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
- {
- MD5::WeightDesc& desc = meshSrc.mWeights[w];
- /* FIX for some invalid exporters */
- if (!(desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON ))
- ++piCount[desc.mBone];
- }
- }
-
- // check how many we will need
- for (unsigned int p = 0; p < meshParser.mJoints.size();++p)
- if (piCount[p])mesh->mNumBones++;
-
- if (mesh->mNumBones) // just for safety
- {
- mesh->mBones = new aiBone*[mesh->mNumBones];
- for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q)
- {
- if (!piCount[q])continue;
- aiBone* p = mesh->mBones[h] = new aiBone();
- p->mNumWeights = piCount[q];
- p->mWeights = new aiVertexWeight[p->mNumWeights];
- p->mName = aiString(meshParser.mJoints[q].mName);
- p->mOffsetMatrix = meshParser.mJoints[q].mInvTransform;
-
- // store the index for later use
- MD5::BoneDesc& boneSrc = meshParser.mJoints[q];
- boneSrc.mMap = h++;
-
- // compute w-component of quaternion
- MD5::ConvertQuaternion( boneSrc.mRotationQuat, boneSrc.mRotationQuatConverted );
- }
-
- //unsigned int g = 0;
- pv = mesh->mVertices;
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- // compute the final vertex position from all single weights
- *pv = aiVector3D();
-
- // there are models which have weights which don't sum to 1 ...
- float fSum = 0.0f;
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
- fSum += meshSrc.mWeights[w].mWeight;
- if (!fSum) {
- DefaultLogger::get()->error("MD5MESH: The sum of all vertex bone weights is 0");
- continue;
- }
-
- // process bone weights
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w) {
- if (w >= meshSrc.mWeights.size())
- throw DeadlyImportError("MD5MESH: Invalid weight index");
-
- MD5::WeightDesc& desc = meshSrc.mWeights[w];
- if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON)
- continue;
-
- const float fNewWeight = desc.mWeight / fSum;
-
- // transform the local position into worldspace
- MD5::BoneDesc& boneSrc = meshParser.mJoints[desc.mBone];
- const aiVector3D v = boneSrc.mRotationQuatConverted.Rotate (desc.vOffsetPosition);
-
- // use the original weight to compute the vertex position
- // (some MD5s seem to depend on the invalid weight values ...)
- *pv += ((boneSrc.mPositionXYZ+v)* desc.mWeight);
-
- aiBone* bone = mesh->mBones[boneSrc.mMap];
- *bone->mWeights++ = aiVertexWeight((unsigned int)(pv-mesh->mVertices),fNewWeight);
- }
- }
-
- // undo our nice offset tricks ...
- for (unsigned int p = 0; p < mesh->mNumBones;++p)
- mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
- }
-
- delete[] piCount;
-
- // now setup all faces - we can directly copy the list
- // (however, take care that the aiFace destructor doesn't delete the mIndices array)
- mesh->mNumFaces = (unsigned int)meshSrc.mFaces.size();
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- for (unsigned int c = 0; c < mesh->mNumFaces;++c) {
- mesh->mFaces[c].mNumIndices = 3;
- mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
- meshSrc.mFaces[c].mIndices = NULL;
- }
-
- // generate a material for the mesh
- MaterialHelper* mat = new MaterialHelper();
- pScene->mMaterials[n] = mat;
-
- // insert the typical doom3 textures:
- // nnn_local.tga - normal map
- // nnn_h.tga - height map
- // nnn_s.tga - specular map
- // nnn_d.tga - diffuse map
- if (meshSrc.mShader.length && !strchr(meshSrc.mShader.data,'.')) {
-
- aiString temp(meshSrc.mShader);
- temp.Append("_local.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_NORMALS(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_s.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_SPECULAR(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_d.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_h.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_HEIGHT(0));
-
- // set this also as material name
- mat->AddProperty(&meshSrc.mShader,AI_MATKEY_NAME);
- }
- else mat->AddProperty(&meshSrc.mShader,AI_MATKEY_TEXTURE_DIFFUSE(0));
- mesh->mMaterialIndex = n++;
- }
-#endif
- // delete the file again
- UnloadFileFromMemory();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load an MD5ANIM file
-void MD5Importer::LoadMD5AnimFile ()
-{
- std::string pFile = mFile + "md5anim";
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- DefaultLogger::get()->warn("Failed to read MD5ANIM file: " + pFile);
- return;
- }
- LoadFileIntoMemory(file.get());
-
- // parse the basic file structure
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the animation information from the parse tree
- MD5::MD5AnimParser animParser(parser.mSections);
-
- // generate and fill the output animation
- if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
- animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
-
- DefaultLogger::get()->error("MD5ANIM: No frames or animated bones loaded");
- }
- else {
- bHadMD5Anim = true;
-
- pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations = 1];
- aiAnimation* anim = pScene->mAnimations[0] = new aiAnimation();
- anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* node = anim->mChannels[i] = new aiNodeAnim();
- node->mNodeName = aiString( animParser.mAnimatedBones[i].mName );
-
- // allocate storage for the keyframes
- node->mPositionKeys = new aiVectorKey[animParser.mFrames.size()];
- node->mRotationKeys = new aiQuatKey[animParser.mFrames.size()];
- }
-
- // 1 tick == 1 frame
- anim->mTicksPerSecond = animParser.fFrameRate;
-
- for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end();iter != iterEnd;++iter){
- double dTime = (double)(*iter).iIndex;
- aiNodeAnim** pcAnimNode = anim->mChannels;
- if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
- {
- // now process all values in there ... read all joints
- MD5::BaseFrameDesc* pcBaseFrame = &animParser.mBaseFrames[0];
- for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end();++iter2,
- ++pcAnimNode,++pcBaseFrame)
- {
- if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
-
- // Allow for empty frames
- if ((*iter2).iFlags != 0) {
- throw DeadlyImportError("MD5: Keyframe index is out of range");
-
- }
- continue;
- }
- const float* fpCur = &(*iter).mValues[(*iter2).iFirstKeyIndex];
- aiNodeAnim* pcCurAnimBone = *pcAnimNode;
-
- aiVectorKey* vKey = &pcCurAnimBone->mPositionKeys[pcCurAnimBone->mNumPositionKeys++];
- aiQuatKey* qKey = &pcCurAnimBone->mRotationKeys [pcCurAnimBone->mNumRotationKeys++];
- aiVector3D vTemp;
-
- // translational component
- for (unsigned int i = 0; i < 3; ++i) {
- if ((*iter2).iFlags & (1u << i))
- vKey->mValue[i] = *fpCur++;
- else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
- }
-
- // orientation component
- for (unsigned int i = 0; i < 3; ++i) {
- if ((*iter2).iFlags & (8u << i))
- vTemp[i] = *fpCur++;
- else vTemp[i] = pcBaseFrame->vRotationQuat[i];
- }
-
- MD5::ConvertQuaternion(vTemp, qKey->mValue);
- qKey->mTime = vKey->mTime = dTime;
-
- // we need this to get to Assimp quaternion conventions
- qKey->mValue.w *= -1.f;
- }
- }
-
- // compute the duration of the animation
- anim->mDuration = std::max(dTime,anim->mDuration);
- }
-
- // If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
- // construct it now from the data given in the MD5ANIM.
- if (!pScene->mRootNode) {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
-
- AttachChilds_Anim(-1,pScene->mRootNode,animParser.mAnimatedBones,(const aiNodeAnim**)anim->mChannels);
-
- // Call SkeletonMeshBuilder to construct a mesh to represent the shape
- if (pScene->mRootNode->mNumChildren) {
- SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[0]);
- }
- }
- }
- // delete the file again
- UnloadFileFromMemory();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load an MD5CAMERA file
-void MD5Importer::LoadMD5CameraFile ()
-{
- std::string pFile = mFile + "md5camera";
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
- }
- bHadMD5Camera = true;
- LoadFileIntoMemory(file.get());
-
- // parse the basic file structure
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the camera animation data from the parse tree
- MD5::MD5CameraParser cameraParser(parser.mSections);
-
- if (cameraParser.frames.empty())
- throw DeadlyImportError("MD5CAMERA: No frames parsed");
-
- std::vector<unsigned int>& cuts = cameraParser.cuts;
- std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;
-
- // Construct output graph - a simple root with a dummy child.
- // The root node performs the coordinate system conversion
- aiNode* root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
- root->mChildren = new aiNode*[root->mNumChildren = 1];
- root->mChildren[0] = new aiNode("<MD5Camera>");
- root->mChildren[0]->mParent = root;
-
- // ... but with one camera assigned to it
- pScene->mCameras = new aiCamera*[pScene->mNumCameras = 1];
- aiCamera* cam = pScene->mCameras[0] = new aiCamera();
- cam->mName = "<MD5Camera>";
-
- // FIXME: Fov is currently set to the first frame's value
- cam->mHorizontalFOV = AI_DEG_TO_RAD( frames.front().fFOV );
-
- // every cut is written to a separate aiAnimation
- if (!cuts.size()) {
- cuts.push_back(0);
- cuts.push_back(frames.size()-1);
- }
- else {
- cuts.insert(cuts.begin(),0);
-
- if (cuts.back() < frames.size()-1)
- cuts.push_back(frames.size()-1);
- }
-
- pScene->mNumAnimations = cuts.size()-1;
- aiAnimation** tmp = pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations];
- for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end()-1; ++it) {
-
- aiAnimation* anim = *tmp++ = new aiAnimation();
- anim->mName.length = ::sprintf(anim->mName.data,"anim%u_from_%u_to_%u",(unsigned int)(it-cuts.begin()),(*it),*(it+1));
-
- anim->mTicksPerSecond = cameraParser.fFrameRate;
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels = 1];
- aiNodeAnim* nd = anim->mChannels[0] = new aiNodeAnim();
- nd->mNodeName.Set("<MD5Camera>");
-
- nd->mNumPositionKeys = nd->mNumRotationKeys = *(it+1) - (*it);
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
- nd->mRotationKeys = new aiQuatKey [nd->mNumRotationKeys];
- for (unsigned int i = 0; i < nd->mNumPositionKeys; ++i) {
-
- nd->mPositionKeys[i].mValue = frames[*it+i].vPositionXYZ;
- MD5::ConvertQuaternion(frames[*it+i].vRotationQuat,nd->mRotationKeys[i].mValue);
- nd->mRotationKeys[i].mTime = nd->mPositionKeys[i].mTime = *it+i;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD5_IMPORTER
diff --git a/3rdparty/assimp/code/MD5Loader.h b/3rdparty/assimp/code/MD5Loader.h
deleted file mode 100644
index 0677eef9..00000000
--- a/3rdparty/assimp/code/MD5Loader.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file MD5Loader.h
- * @brief Definition of the .MD5 importer class.
- * http://www.modwiki.net/wiki/MD5_(file_format)
-*/
-#ifndef AI_MD5LOADER_H_INCLUDED
-#define AI_MD5LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "MD5Parser.h"
-
-#include "../include/aiTypes.h"
-
-namespace Assimp {
-
-class IOStream;
-using namespace Assimp::MD5;
-
-// ---------------------------------------------------------------------------
-/** Importer class for the MD5 file format
-*/
-class MD5Importer : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- MD5Importer();
-
- /** Destructor, private as well */
- ~MD5Importer();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Load a *.MD5MESH file.
- */
- void LoadMD5MeshFile ();
-
- // -------------------------------------------------------------------
- /** Load a *.MD5ANIM file.
- */
- void LoadMD5AnimFile ();
-
- // -------------------------------------------------------------------
- /** Load a *.MD5CAMERA file.
- */
- void LoadMD5CameraFile ();
-
- // -------------------------------------------------------------------
- /** Construct node hierarchy from a given MD5ANIM
- * @param iParentID Current parent ID
- * @param piParent Parent node to attach to
- * @param bones Input bones
- * @param node_anims Generated node animations
- */
- void AttachChilds_Anim(int iParentID,aiNode* piParent,
- AnimBoneList& bones,const aiNodeAnim** node_anims);
-
- // -------------------------------------------------------------------
- /** Construct node hierarchy from a given MD5MESH
- * @param iParentID Current parent ID
- * @param piParent Parent node to attach to
- * @param bones Input bones
- */
- void AttachChilds_Mesh(int iParentID,aiNode* piParent,BoneList& bones);
-
- // -------------------------------------------------------------------
- /** Build unique vertex buffers from a given MD5ANIM
- * @param meshSrc Input data
- */
- void MakeDataUnique (MD5::MeshDesc& meshSrc);
-
- // -------------------------------------------------------------------
- /** Load the contents of a specific file into memory and
- * alocates a buffer to keep it.
- *
- * mBuffer is modified to point to this buffer.
- * @param pFile File stream to be read
- */
- void LoadFileIntoMemory (IOStream* pFile);
- void UnloadFileFromMemory ();
-
-
- /** IOSystem to be used to access files */
- IOSystem* mIOHandler;
-
- /** Path to the file, excluding the file extension but
- with the dot */
- std::string mFile;
-
- /** Buffer to hold the loaded file */
- char* mBuffer;
-
- /** Size of the file */
- unsigned int fileSize;
-
- /** Current line number. For debugging purposes */
- unsigned int iLineNumber;
-
- /** Scene to be filled */
- aiScene* pScene;
-
- /** (Custom) I/O handler implementation */
- IOSystem* pIOHandler;
-
- /** true if a MD5MESH file has already been parsed */
- bool bHadMD5Mesh;
-
- /** true if a MD5ANIM file has already been parsed */
- bool bHadMD5Anim;
-
- /** true if a MD5CAMERA file has already been parsed */
- bool bHadMD5Camera;
-
- /** configuration option: prevent anim autoload */
- bool configNoAutoLoad;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/MD5Parser.cpp b/3rdparty/assimp/code/MD5Parser.cpp
deleted file mode 100644
index 5541b299..00000000
--- a/3rdparty/assimp/code/MD5Parser.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MD5Parser.cpp
- * @brief Implementation of the MD5 parser class
- */
-#include "AssimpPCH.h"
-
-// internal headers
-#include "MD5Loader.h"
-#include "MaterialSystem.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "StringComparison.h"
-
-using namespace Assimp;
-using namespace Assimp::MD5;
-
-// ------------------------------------------------------------------------------------------------
-// Parse the segment structure fo a MD5 file
-MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
-{
- ai_assert(NULL != _buffer && 0 != _fileSize);
-
- buffer = _buffer;
- fileSize = _fileSize;
- lineNumber = 0;
-
- DefaultLogger::get()->debug("MD5Parser begin");
-
- // parse the file header
- ParseHeader();
-
- // and read all sections until we're finished
- bool running = true;
- while (running) {
- mSections.push_back(Section());
- Section& sec = mSections.back();
- if (!ParseSection(sec)) {
- break;
- }
- }
-
- if ( !DefaultLogger::isNullLogger()) {
- char szBuffer[128]; // should be sufficiently large
- ::sprintf(szBuffer,"MD5Parser end. Parsed %i sections",(int)mSections.size());
- DefaultLogger::get()->debug(szBuffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Report error to the log stream
-/*static*/ void MD5Parser::ReportError (const char* error, unsigned int line)
-{
- char szBuffer[1024];
- ::sprintf(szBuffer,"[MD5] Line %i: %s",line,error);
- throw DeadlyImportError(szBuffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Report warning to the log stream
-/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
-{
- char szBuffer[1024];
- ::sprintf(szBuffer,"[MD5] Line %i: %s",line,warn);
- DefaultLogger::get()->warn(szBuffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse and validate the MD5 header
-void MD5Parser::ParseHeader()
-{
- // parse and validate the file version
- SkipSpaces();
- if (!TokenMatch(buffer,"MD5Version",10)) {
- ReportError("Invalid MD5 file: MD5Version tag has not been found");
- }
- SkipSpaces();
- unsigned int iVer = ::strtol10(buffer,(const char**)&buffer);
- if (10 != iVer) {
- ReportError("MD5 version tag is unknown (10 is expected)");
- }
- SkipLine();
-
- // print the command line options to the console
- // FIX: can break the log length limit, so we need to be careful
- char* sz = buffer;
- while (!IsLineEnd( *buffer++)) {};
- DefaultLogger::get()->info(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
- SkipSpacesAndLineEnd();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive MD5 parsing function
-bool MD5Parser::ParseSection(Section& out)
-{
- // store the current line number for use in error messages
- out.iLineNumber = lineNumber;
-
- // first parse the name of the section
- char* sz = buffer;
- while (!IsSpaceOrNewLine( *buffer))buffer++;
- out.mName = std::string(sz,(uintptr_t)(buffer-sz));
- SkipSpaces();
-
- bool running = true;
- while (running) {
- if ('{' == *buffer) {
- // it is a normal section so read all lines
- buffer++;
- bool run = true;
- while (run)
- {
- if (!SkipSpacesAndLineEnd()) {
- return false; // seems this was the last section
- }
- if ('}' == *buffer) {
- buffer++;
- break;
- }
-
- out.mElements.push_back(Element());
- Element& elem = out.mElements.back();
-
- elem.iLineNumber = lineNumber;
- elem.szStart = buffer;
-
- // terminate the line with zero
- while (!IsLineEnd( *buffer))buffer++;
- if (*buffer) {
- ++lineNumber;
- *buffer++ = '\0';
- }
- }
- break;
- }
- else if (!IsSpaceOrNewLine(*buffer)) {
- // it is an element at global scope. Parse its value and go on
- sz = buffer;
- while (!IsSpaceOrNewLine( *buffer++)) {};
- out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz));
- continue;
- }
- break;
- }
- return SkipSpacesAndLineEnd();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Some dirty macros just because they're so funny and easy to debug
-
-// skip all spaces ... handle EOL correctly
-#define AI_MD5_SKIP_SPACES() if (!SkipSpaces(&sz)) \
- MD5Parser::ReportWarning("Unexpected end of line",(*eit).iLineNumber);
-
- // read a triple float in brackets: (1.0 1.0 1.0)
-#define AI_MD5_READ_TRIPLE(vec) \
- AI_MD5_SKIP_SPACES(); \
- if ('(' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atof_move(sz,(float&)vec.x); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atof_move(sz,(float&)vec.y); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atof_move(sz,(float&)vec.z); \
- AI_MD5_SKIP_SPACES(); \
- if (')' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
-
- // parse a string, enclosed in quotation marks or not
-#define AI_MD5_PARSE_STRING(out) \
- bool bQuota = (*sz == '\"'); \
- const char* szStart = sz; \
- while (!IsSpaceOrNewLine(*sz))++sz; \
- const char* szEnd = sz; \
- if (bQuota) { \
- szStart++; \
- if ('\"' != *(szEnd-=1)) { \
- MD5Parser::ReportWarning("Expected closing quotation marks in string", \
- (*eit).iLineNumber); \
- continue; \
- } \
- } \
- out.length = (size_t)(szEnd - szStart); \
- ::memcpy(out.data,szStart,out.length); \
- out.data[out.length] = '\0';
-
-// ------------------------------------------------------------------------------------------------
-// .MD5MESH parsing function
-MD5MeshParser::MD5MeshParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5MeshParser begin");
-
- // now parse all sections
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
- if ( (*iter).mName == "numMeshes") {
- mMeshes.reserve(::strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ( (*iter).mName == "numJoints") {
- mJoints.reserve(::strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "joints") {
- // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
- mJoints.push_back(BoneDesc());
- BoneDesc& desc = mJoints.back();
-
- const char* sz = (*eit).szStart;
- AI_MD5_PARSE_STRING(desc.mName);
- AI_MD5_SKIP_SPACES();
-
- // negative values, at least -1, is allowed here
- desc.mParentIndex = (int)strtol10s(sz,&sz);
-
- AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
- }
- }
- else if ((*iter).mName == "mesh") {
- mMeshes.push_back(MeshDesc());
- MeshDesc& desc = mMeshes.back();
-
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
- const char* sz = (*eit).szStart;
-
- // shader attribute
- if (TokenMatch(sz,"shader",6)) {
- AI_MD5_SKIP_SPACES();
- AI_MD5_PARSE_STRING(desc.mShader);
- }
- // numverts attribute
- else if (TokenMatch(sz,"numverts",8)) {
- AI_MD5_SKIP_SPACES();
- desc.mVertices.resize(strtol10(sz));
- }
- // numtris attribute
- else if (TokenMatch(sz,"numtris",7)) {
- AI_MD5_SKIP_SPACES();
- desc.mFaces.resize(strtol10(sz));
- }
- // numweights attribute
- else if (TokenMatch(sz,"numweights",10)) {
- AI_MD5_SKIP_SPACES();
- desc.mWeights.resize(strtol10(sz));
- }
- // vert attribute
- // "vert 0 ( 0.394531 0.513672 ) 0 1"
- else if (TokenMatch(sz,"vert",4)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = ::strtol10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- if (idx >= desc.mVertices.size())
- desc.mVertices.resize(idx+1);
-
- VertexDesc& vert = desc.mVertices[idx];
- if ('(' != *sz++)
- MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber);
- AI_MD5_SKIP_SPACES();
- sz = fast_atof_move(sz,(float&)vert.mUV.x);
- AI_MD5_SKIP_SPACES();
- sz = fast_atof_move(sz,(float&)vert.mUV.y);
- AI_MD5_SKIP_SPACES();
- if (')' != *sz++)
- MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
- AI_MD5_SKIP_SPACES();
- vert.mFirstWeight = ::strtol10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- vert.mNumWeights = ::strtol10(sz,&sz);
- }
- // tri attribute
- // "tri 0 15 13 12"
- else if (TokenMatch(sz,"tri",3)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = strtol10(sz,&sz);
- if (idx >= desc.mFaces.size())
- desc.mFaces.resize(idx+1);
-
- aiFace& face = desc.mFaces[idx];
- face.mIndices = new unsigned int[face.mNumIndices = 3];
- for (unsigned int i = 0; i < 3;++i) {
- AI_MD5_SKIP_SPACES();
- face.mIndices[i] = strtol10(sz,&sz);
- }
- }
- // weight attribute
- // "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
- else if (TokenMatch(sz,"weight",6)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = strtol10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- if (idx >= desc.mWeights.size())
- desc.mWeights.resize(idx+1);
-
- WeightDesc& weight = desc.mWeights[idx];
- weight.mBone = strtol10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- sz = fast_atof_move(sz,weight.mWeight);
- AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
- }
- }
- }
- }
- DefaultLogger::get()->debug("MD5MeshParser end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// .MD5ANIM parsing function
-MD5AnimParser::MD5AnimParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5AnimParser begin");
-
- fFrameRate = 24.0f;
- mNumAnimatedComponents = 0xffffffff;
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
- if ((*iter).mName == "hierarchy") {
- // "sheath" 0 63 6
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit) {
- mAnimatedBones.push_back ( AnimBoneDesc () );
- AnimBoneDesc& desc = mAnimatedBones.back();
-
- const char* sz = (*eit).szStart;
- AI_MD5_PARSE_STRING(desc.mName);
- AI_MD5_SKIP_SPACES();
-
- // parent index - negative values are allowed (at least -1)
- desc.mParentIndex = ::strtol10s(sz,&sz);
-
- // flags (highest is 2^6-1)
- AI_MD5_SKIP_SPACES();
- if (63 < (desc.iFlags = ::strtol10(sz,&sz))){
- MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",(*eit).iLineNumber);
- }
- AI_MD5_SKIP_SPACES();
-
- // index of the first animation keyframe component for this joint
- desc.iFirstKeyIndex = ::strtol10(sz,&sz);
- }
- }
- else if ((*iter).mName == "baseframe") {
- // ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit) {
- const char* sz = (*eit).szStart;
-
- mBaseFrames.push_back ( BaseFrameDesc () );
- BaseFrameDesc& desc = mBaseFrames.back();
-
- AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.vRotationQuat);
- }
- }
- else if ((*iter).mName == "frame") {
- if (!(*iter).mGlobalValue.length()) {
- MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber);
- continue;
- }
-
- mFrames.push_back ( FrameDesc () );
- FrameDesc& desc = mFrames.back();
- desc.iIndex = strtol10((*iter).mGlobalValue.c_str());
-
- // we do already know how much storage we will presumably need
- if (0xffffffff != mNumAnimatedComponents)
- desc.mValues.reserve(mNumAnimatedComponents);
-
- // now read all elements (continous list of floats)
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
- const char* sz = (*eit).szStart;
- while (SkipSpacesAndLineEnd(&sz)) {
- float f;sz = fast_atof_move(sz,f);
- desc.mValues.push_back(f);
- }
- }
- }
- else if ((*iter).mName == "numFrames") {
- mFrames.reserve(strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "numJoints") {
- const unsigned int num = strtol10((*iter).mGlobalValue.c_str());
- mAnimatedBones.reserve(num);
-
- // try to guess the number of animated components if that element is not given
- if (0xffffffff == mNumAnimatedComponents)
- mNumAnimatedComponents = num * 6;
- }
- else if ((*iter).mName == "numAnimatedComponents") {
- mAnimatedBones.reserve( strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "frameRate") {
- fast_atof_move((*iter).mGlobalValue.c_str(),fFrameRate);
- }
- }
- DefaultLogger::get()->debug("MD5AnimParser end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// .MD5CAMERA parsing function
-MD5CameraParser::MD5CameraParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5CameraParser begin");
- fFrameRate = 24.0f;
-
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
- if ((*iter).mName == "numFrames") {
- frames.reserve(strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "frameRate") {
- fFrameRate = fast_atof ((*iter).mGlobalValue.c_str());
- }
- else if ((*iter).mName == "numCuts") {
- cuts.reserve(strtol10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "cuts") {
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
- cuts.push_back(strtol10((*eit).szStart)+1);
- }
- }
- else if ((*iter).mName == "camera") {
- for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
- const char* sz = (*eit).szStart;
-
- frames.push_back(CameraAnimFrameDesc());
- CameraAnimFrameDesc& cur = frames.back();
- AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
- AI_MD5_READ_TRIPLE(cur.vRotationQuat);
- AI_MD5_SKIP_SPACES();
- cur.fFOV = fast_atof(sz);
- }
- }
- }
- DefaultLogger::get()->debug("MD5CameraParser end");
-}
-
diff --git a/3rdparty/assimp/code/MD5Parser.h b/3rdparty/assimp/code/MD5Parser.h
deleted file mode 100644
index 33a0e4d8..00000000
--- a/3rdparty/assimp/code/MD5Parser.h
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file MD5Parser.h
- * @brief Definition of the .MD5 parser class.
- * http://www.modwiki.net/wiki/MD5_(file_format)
- */
-#ifndef AI_MD5PARSER_H_INCLUDED
-#define AI_MD5PARSER_H_INCLUDED
-
-#include "../include/aiTypes.h"
-#include "ParsingUtils.h"
-
-struct aiFace;
-
-namespace Assimp {
-namespace MD5 {
-
-// ---------------------------------------------------------------------------
-/** Represents a single element in a MD5 file
- *
- * Elements are always contained in sections.
-*/
-struct Element
-{
- //! Points to the starting point of the element
- //! Whitespace at the beginning and at the end have been removed,
- //! Elements are terminated with \0
- char* szStart;
-
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
-};
-
-typedef std::vector< Element > ElementList;
-
-// ---------------------------------------------------------------------------
-/** Represents a section of a MD5 file (such as the mesh or the joints section)
- *
- * A section is always enclosed in { and } brackets.
-*/
-struct Section
-{
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
-
- //! List of all elements which have been parsed in this section.
- ElementList mElements;
-
- //! Name of the section
- std::string mName;
-
- //! For global elements: the value of the element as string
- //! Iif !length() the section is not a global element
- std::string mGlobalValue;
-};
-
-typedef std::vector< Section> SectionList;
-
-// ---------------------------------------------------------------------------
-/** Basic information about a joint
-*/
-struct BaseJointDescription
-{
- //! Name of the bone
- aiString mName;
-
- //! Parent index of the bone
- int mParentIndex;
-};
-
-// ---------------------------------------------------------------------------
-/** Represents a bone (joint) descriptor in a MD5Mesh file
-*/
-struct BoneDesc : BaseJointDescription
-{
- //! Absolute position of the bone
- aiVector3D mPositionXYZ;
-
- //! Absolute rotation of the bone
- aiVector3D mRotationQuat;
- aiQuaternion mRotationQuatConverted;
-
- //! Absolute transformation of the bone
- //! (temporary)
- aiMatrix4x4 mTransform;
-
- //! Inverse transformation of the bone
- //! (temporary)
- aiMatrix4x4 mInvTransform;
-
- //! Internal
- unsigned int mMap;
-};
-
-typedef std::vector< BoneDesc > BoneList;
-
-// ---------------------------------------------------------------------------
-/** Represents a bone (joint) descriptor in a MD5Anim file
-*/
-struct AnimBoneDesc : BaseJointDescription
-{
- //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
- unsigned int iFlags;
-
- //! Index of the first key that corresponds to this anim bone
- unsigned int iFirstKeyIndex;
-};
-
-typedef std::vector< AnimBoneDesc > AnimBoneList;
-
-
-// ---------------------------------------------------------------------------
-/** Represents a base frame descriptor in a MD5Anim file
-*/
-struct BaseFrameDesc
-{
- aiVector3D vPositionXYZ;
- aiVector3D vRotationQuat;
-};
-
-typedef std::vector< BaseFrameDesc > BaseFrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a camera animation frame in a MDCamera file
-*/
-struct CameraAnimFrameDesc : BaseFrameDesc
-{
- float fFOV;
-};
-
-typedef std::vector< CameraAnimFrameDesc > CameraFrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a frame descriptor in a MD5Anim file
-*/
-struct FrameDesc
-{
- //! Index of the frame
- unsigned int iIndex;
-
- //! Animation keyframes - a large blob of data at first
- std::vector< float > mValues;
-};
-
-typedef std::vector< FrameDesc > FrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a vertex descriptor in a MD5 file
-*/
-struct VertexDesc
-{
- VertexDesc()
- : mFirstWeight (0)
- , mNumWeights (0)
- {}
-
- //! UV cordinate of the vertex
- aiVector2D mUV;
-
- //! Index of the first weight of the vertex in
- //! the vertex weight list
- unsigned int mFirstWeight;
-
- //! Number of weights assigned to this vertex
- unsigned int mNumWeights;
-};
-
-typedef std::vector< VertexDesc > VertexList;
-
-// ---------------------------------------------------------------------------
-/** Represents a vertex weight descriptor in a MD5 file
-*/
-struct WeightDesc
-{
- //! Index of the bone to which this weight refers
- unsigned int mBone;
-
- //! The weight value
- float mWeight;
-
- //! The offset position of this weight
- // ! (in the coordinate system defined by the parent bone)
- aiVector3D vOffsetPosition;
-};
-
-typedef std::vector< WeightDesc > WeightList;
-typedef std::vector< aiFace > FaceList;
-
-// ---------------------------------------------------------------------------
-/** Represents a mesh in a MD5 file
-*/
-struct MeshDesc
-{
- //! Weights of the mesh
- WeightList mWeights;
-
- //! Vertices of the mesh
- VertexList mVertices;
-
- //! Faces of the mesh
- FaceList mFaces;
-
- //! Name of the shader (=texture) to be assigned to the mesh
- aiString mShader;
-};
-
-typedef std::vector< MeshDesc > MeshList;
-
-// ---------------------------------------------------------------------------
-// Convert a quaternion to its usual representation
-inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
-
- out.x = in.x;
- out.y = in.y;
- out.z = in.z;
-
- const float t = 1.0f - (in.x*in.x) - (in.y*in.y) - (in.z*in.z);
-
- if (t < 0.0f)
- out.w = 0.0f;
- else out.w = sqrt (t);
-}
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 mesh file
-*/
-class MD5MeshParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5MeshParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- MD5MeshParser(SectionList& mSections);
-
- //! List of all meshes
- MeshList mMeshes;
-
- //! List of all joints
- BoneList mJoints;
-};
-
-// remove this flag if you need to the bounding box data
-#define AI_MD5_PARSE_NO_BOUNDS
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 animation file
-*/
-class MD5AnimParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5AnimParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- MD5AnimParser(SectionList& mSections);
-
-
- //! Output frame rate
- float fFrameRate;
-
- //! List of animation bones
- AnimBoneList mAnimatedBones;
-
- //! List of base frames
- BaseFrameList mBaseFrames;
-
- //! List of animation frames
- FrameList mFrames;
-
- //! Number of animated components
- unsigned int mNumAnimatedComponents;
-};
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 camera animation file
-*/
-class MD5CameraParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5CameraParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- MD5CameraParser(SectionList& mSections);
-
-
- //! Output frame rate
- float fFrameRate;
-
- //! List of cuts
- std::vector<unsigned int> cuts;
-
- //! Frames
- CameraFrameList frames;
-};
-
-// ---------------------------------------------------------------------------
-/** Parses the block structure of MD5MESH and MD5ANIM files (but does no
- * further processing)
-*/
-class MD5Parser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5Parser instance from an existing buffer.
- *
- * @param buffer File buffer
- * @param fileSize Length of the file in bytes (excluding a terminal 0)
- */
- MD5Parser(char* buffer, unsigned int fileSize);
-
-
- // -------------------------------------------------------------------
- /** Report a specific error message and throw an exception
- * @param error Error message to be reported
- * @param line Index of the line where the error occured
- */
- static void ReportError (const char* error, unsigned int line);
-
- // -------------------------------------------------------------------
- /** Report a specific warning
- * @param warn Warn message to be reported
- * @param line Index of the line where the error occured
- */
- static void ReportWarning (const char* warn, unsigned int line);
-
-
- void ReportError (const char* error) {
- return ReportError(error, lineNumber);
- }
-
- void ReportWarning (const char* warn) {
- return ReportWarning(warn, lineNumber);
- }
-
-public:
-
- //! List of all sections which have been read
- SectionList mSections;
-
-private:
-
- // -------------------------------------------------------------------
- /** Parses a file section. The current file pointer must be outside
- * of a section.
- * @param out Receives the section data
- * @return true if the end of the file has been reached
- * @throws ImportErrorException if an error occurs
- */
- bool ParseSection(Section& out);
-
- // -------------------------------------------------------------------
- /** Parses the file header
- * @throws ImportErrorException if an error occurs
- */
- void ParseHeader();
-
-
- // override these functions to make sure the line counter gets incremented
- // -------------------------------------------------------------------
- bool SkipLine( const char* in, const char** out)
- {
- ++lineNumber;
- return Assimp::SkipLine(in,out);
- }
- // -------------------------------------------------------------------
- bool SkipLine( )
- {
- return SkipLine(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- bool SkipSpacesAndLineEnd( const char* in, const char** out)
- {
- bool bHad = false;
- bool running = true;
- while (running) {
- if ( *in == '\r' || *in == '\n') {
- // we open files in binary mode, so there could be \r\n sequences ...
- if (!bHad) {
- bHad = true;
- ++lineNumber;
- }
- }
- else if (*in == '\t' || *in == ' ')bHad = false;
- else break;
- in++;
- }
- *out = in;
- return *in != '\0';
- }
- // -------------------------------------------------------------------
- bool SkipSpacesAndLineEnd( )
- {
- return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- bool SkipSpaces( )
- {
- return Assimp::SkipSpaces((const char**)&buffer);
- }
-
- char* buffer;
- unsigned int fileSize;
- unsigned int lineNumber;
-};
-}}
-
-#endif // AI_MD5PARSER_H_INCLUDED
diff --git a/3rdparty/assimp/code/MDCFileData.h b/3rdparty/assimp/code/MDCFileData.h
deleted file mode 100644
index 3208c3fa..00000000
--- a/3rdparty/assimp/code/MDCFileData.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines the helper data structures for importing MDC files
-
-**********************************************************************
-File format specification:
-http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
-**********************************************************************
-
-*/
-#ifndef AI_MDCFILEHELPER_H_INC
-#define AI_MDCFILEHELPER_H_INC
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-#include "./../include/Compiler/pushpack1.h"
-
-
-namespace Assimp {
-namespace MDC {
-
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
-#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
-
-// common limitations
-#define AI_MDC_VERSION 2
-#define AI_MDC_MAXQPATH 64
-#define AI_MDC_MAX_BONES 128
-
-#define AI_MDC_CVERT_BIAS 127.0f
-#define AI_MDC_DELTA_SCALING 4.0f
-#define AI_MDC_BASE_SCALING (1.0f / 64.0f)
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC file's main header
- */
-struct Header
-{
- uint32_t ulIdent ;
- uint32_t ulVersion ;
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulFlags ;
- uint32_t ulNumFrames ;
- uint32_t ulNumTags ;
- uint32_t ulNumSurfaces ;
- uint32_t ulNumSkins ;
- uint32_t ulOffsetBorderFrames ;
- uint32_t ulOffsetTagNames ;
- uint32_t ulOffsetTagFrames ;
- uint32_t ulOffsetSurfaces ;
- uint32_t ulOffsetEnd ;
-} PACK_STRUCT ;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC file's surface header
- */
-struct Surface
-{
- uint32_t ulIdent ;
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulFlags ;
- uint32_t ulNumCompFrames ;
- uint32_t ulNumBaseFrames ;
- uint32_t ulNumShaders ;
- uint32_t ulNumVertices ;
- uint32_t ulNumTriangles ;
- uint32_t ulOffsetTriangles ;
- uint32_t ulOffsetShaders ;
- uint32_t ulOffsetTexCoords ;
- uint32_t ulOffsetBaseVerts ;
- uint32_t ulOffsetCompVerts ;
- uint32_t ulOffsetFrameBaseFrames ;
- uint32_t ulOffsetFrameCompFrames ;
- uint32_t ulOffsetEnd ;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC frame
- */
-struct Frame
-{
- //! bounding box minimum coords
- aiVector3D bboxMin ;
-
- //! bounding box maximum coords
- aiVector3D bboxMax ;
-
- //! local origin of the frame
- aiVector3D localOrigin ;
-
- //! radius of the BB
- float radius ;
-
- //! Name of the frame
- char name [ 16 ] ;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC triangle
- */
-struct Triangle
-{
- uint32_t aiIndices[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC texture coordinate
- */
-struct TexturCoord
-{
- float u,v;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC base vertex
- */
-struct BaseVertex
-{
- int16_t x,y,z;
- uint16_t normal;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC compressed vertex
- */
-struct CompressedVertex
-{
- uint8_t xd,yd,zd,nd;
-} PACK_STRUCT;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC shader
- */
-struct Shader
-{
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulPath;
-
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-
-// ---------------------------------------------------------------------------
-/** Build a floating point vertex from the compressed data in MDC files
- */
-void BuildVertex(const Frame& frame,
- const BaseVertex& bvert,
- const CompressedVertex& cvert,
- aiVector3D& vXYZOut,
- aiVector3D& vNorOut);
-}}
-
-#endif // !! AI_MDCFILEHELPER_H_INC
diff --git a/3rdparty/assimp/code/MDCLoader.cpp b/3rdparty/assimp/code/MDCLoader.cpp
deleted file mode 100644
index 077f3b0a..00000000
--- a/3rdparty/assimp/code/MDCLoader.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the MDC importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-
-// internal headers
-#include "MDCLoader.h"
-#include "MD3FileData.h"
-#include "MDCNormalTable.h" // shouldn't be included by other units
-
-using namespace Assimp;
-using namespace Assimp::MDC;
-
-
-// ------------------------------------------------------------------------------------------------
-void MDC::BuildVertex(const Frame& frame,
- const BaseVertex& bvert,
- const CompressedVertex& cvert,
- aiVector3D& vXYZOut,
- aiVector3D& vNorOut)
-{
- // compute the position
- const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
- vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
- vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
-
- // compute the normal vector .. ehm ... lookup it in the table :-)
- vNorOut.x = mdcNormals[cvert.nd][0];
- vNorOut.y = mdcNormals[cvert.nd][1];
- vNorOut.z = mdcNormals[cvert.nd][2];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MDCImporter::MDCImporter()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MDCImporter::~MDCImporter()
-{
-}
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "mdc")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MDCImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("mdc");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of the given MDC file
-void MDCImporter::ValidateHeader()
-{
- AI_SWAP4( this->pcHeader->ulVersion );
- AI_SWAP4( this->pcHeader->ulFlags );
- AI_SWAP4( this->pcHeader->ulNumFrames );
- AI_SWAP4( this->pcHeader->ulNumTags );
- AI_SWAP4( this->pcHeader->ulNumSurfaces );
- AI_SWAP4( this->pcHeader->ulNumSkins );
- AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
-
- if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
- pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
- {
- char szBuffer[5];
- szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
- szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
- szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
- szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
- szBuffer[4] = '\0';
-
- throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
- "magic word found is " + std::string( szBuffer ));
- }
-
- if (pcHeader->ulVersion != AI_MDC_VERSION)
- DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
-
- if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
- pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
- {
- throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
- "and point to something behind the file.");
- }
-
- if (this->configFrameID >= this->pcHeader->ulNumFrames)
- throw DeadlyImportError("The requested frame is not available");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of a given MDC file surface
-void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
-{
- AI_SWAP4(pcSurf->ulFlags);
- AI_SWAP4(pcSurf->ulNumCompFrames);
- AI_SWAP4(pcSurf->ulNumBaseFrames);
- AI_SWAP4(pcSurf->ulNumShaders);
- AI_SWAP4(pcSurf->ulNumVertices);
- AI_SWAP4(pcSurf->ulNumTriangles);
- AI_SWAP4(pcSurf->ulOffsetTriangles);
- AI_SWAP4(pcSurf->ulOffsetTexCoords);
- AI_SWAP4(pcSurf->ulOffsetBaseVerts);
- AI_SWAP4(pcSurf->ulOffsetCompVerts);
- AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
- AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
- AI_SWAP4(pcSurf->ulOffsetEnd);
-
- const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcSurf-(int8_t*)pcHeader);
-
- if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex) > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex) > iMax) ||
- pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle) > iMax ||
- pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
- pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
- pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax))
- {
- throw DeadlyImportError("Some of the offset values in the MDC surface header "
- "are invalid and point somewhere behind the file.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MDCImporter::SetupProperties(const Importer* pImp)
-{
- // The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- if (0xffffffff == (this->configFrameID = pImp->GetPropertyInteger(
- AI_CONFIG_IMPORT_MDC_KEYFRAME,0xffffffff)))
- {
- this->configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MDCImporter::InternReadFile(
- const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
-
- // check whether the mdc file is large enough to contain the file header
- fileSize = (unsigned int)file->FileSize();
- if ( fileSize < sizeof(MDC::Header))
- throw DeadlyImportError( "MDC File is too small.");
-
- std::vector<unsigned char> mBuffer2(fileSize);
- file->Read( &mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
- // validate the file header
- this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
- this->ValidateHeader();
-
- std::vector<std::string> aszShaders;
-
- // get a pointer to the frame we want to read
- BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
- this->pcHeader->ulOffsetBorderFrames);
-
- // no need to swap the other members, we won't need them
- pcFrame += configFrameID;
- AI_SWAP4( pcFrame->localOrigin[0] );
- AI_SWAP4( pcFrame->localOrigin[1] );
- AI_SWAP4( pcFrame->localOrigin[2] );
-
- // get the number of valid surfaces
- BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
- pcSurface = pcSurface2 = (BE_NCONST MDC::Surface*)(mBuffer + pcHeader->ulOffsetSurfaces);
- unsigned int iNumShaders = 0;
- for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- // validate the surface header
- this->ValidateSurfaceHeader(pcSurface2);
-
- if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
- iNumShaders += pcSurface2->ulNumShaders;
- pcSurface2 = (BE_NCONST MDC::Surface*)((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd);
- }
- aszShaders.reserve(iNumShaders);
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- // necessary that we don't crash if an exception occurs
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i] = NULL;
-
- // now read all surfaces
- unsigned int iDefaultMatIndex = 0xffffffff;
- for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
- aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
-
- pcMesh->mNumFaces = pcSurface->ulNumTriangles;
- pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
-
- // store the name of the surface for use as node name.
- // FIX: make sure there is a 0 termination
- const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
- pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
-
- // go to the first shader in the file. ignore the others.
- if (pcSurface->ulNumShaders)
- {
- const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
- pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
-
- // create a new shader
- aszShaders.push_back(std::string( pcShader->ucName, std::min(
- ::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
- }
- // need to create a default material
- else if (0xffffffff == iDefaultMatIndex)
- {
- pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
- aszShaders.push_back(std::string());
- }
- // otherwise assign a reference to the default material
- else pcMesh->mMaterialIndex = iDefaultMatIndex;
-
- // allocate output storage for the mesh
- aiVector3D* pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcNorCur = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcUVCur = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- aiFace* pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- // create all vertices/faces
- BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
-
- BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
-
- // get a pointer to the uncompressed vertices
- int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
- pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID);
-
- AI_SWAP2(iOfs);
-
- BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
- ((int)iOfs * pcSurface->ulNumVertices * 4);
-
- // do the main swapping stuff ...
-#if (defined AI_BUILD_BIG_ENDIAN)
-
- // swap all triangles
- for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
- {
- AI_SWAP4( pcTriangle[i].aiIndices[0] );
- AI_SWAP4( pcTriangle[i].aiIndices[1] );
- AI_SWAP4( pcTriangle[i].aiIndices[2] );
- }
-
- // swap all vertices
- for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
- {
- AI_SWAP2( pcVerts->normal );
- AI_SWAP2( pcVerts->x );
- AI_SWAP2( pcVerts->y );
- AI_SWAP2( pcVerts->z );
- }
-
- // swap all texture coordinates
- for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
- {
- AI_SWAP4( pcUVs->v );
- AI_SWAP4( pcUVs->v );
- }
-
-#endif
-
- const MDC::CompressedVertex* pcCVerts = NULL;
- int16_t* mdcCompVert = NULL;
-
- // access compressed frames for large frame numbers, but never for the first
- if ( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
- {
- mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
- AI_SWAP2P(mdcCompVert);
- if ( *mdcCompVert >= 0 )
- {
- pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
- pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
- }
- else mdcCompVert = NULL;
- }
-
- // copy all faces
- for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
- ++pcTriangle,++pcFaceCur)
- {
- const unsigned int iOutIndex = iFace*3;
- pcFaceCur->mNumIndices = 3;
- pcFaceCur->mIndices = new unsigned int[3];
-
- for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
- ++pcVertCur,++pcUVCur,++pcNorCur)
- {
- uint32_t quak = pcTriangle->aiIndices[iIndex];
- if (quak >= pcSurface->ulNumVertices)
- {
- DefaultLogger::get()->error("MDC vertex index is out of range");
- quak = pcSurface->ulNumVertices-1;
- }
-
- // compressed vertices?
- if (mdcCompVert)
- {
- MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
- *pcVertCur,*pcNorCur);
- }
- else
- {
- // copy position
- pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
- pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
- pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
-
- // copy normals
- MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
-
- // copy texture coordinates
- pcUVCur->x = pcUVs[quak].u;
- pcUVCur->y = 1.0f-pcUVs[quak].v; // DX to OGL
- }
- pcVertCur->x += pcFrame->localOrigin[0] ;
- pcVertCur->y += pcFrame->localOrigin[1] ;
- pcVertCur->z += pcFrame->localOrigin[2] ;
- }
-
- // swap the face order - DX to OGL
- pcFaceCur->mIndices[0] = iOutIndex + 2;
- pcFaceCur->mIndices[1] = iOutIndex + 1;
- pcFaceCur->mIndices[2] = iOutIndex + 0;
- }
-
- pcSurface = (BE_NCONST MDC::Surface*)((int8_t*)pcSurface + pcSurface->ulOffsetEnd);
- }
-
- // create a flat node graph with a root node and one child for each surface
- if (!pScene->mNumMeshes)
- throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
- else if (1 == pScene->mNumMeshes)
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
- pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
- pScene->mRootNode->mName.Set("<root>");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
- pcNode->mNumMeshes = 1;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- }
- }
-
- // make sure we invalidate the pointer to the mesh name
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i]->mTextureCoords[3] = NULL;
-
- // create materials
- pScene->mNumMaterials = (unsigned int)aszShaders.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- MaterialHelper* pcMat = new MaterialHelper();
- pScene->mMaterials[i] = pcMat;
-
- const std::string& name = aszShaders[i];
-
- int iMode = (int)aiShadingMode_Gouraud;
- pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // add a small ambient color value - RtCW seems to have one
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.05f;
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- if (name.length())clr.b = clr.g = clr.r = 1.0f;
- else clr.b = clr.g = clr.r = 0.6f;
-
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- if (name.length())
- {
- aiString path;
- path.Set(name);
- pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER
diff --git a/3rdparty/assimp/code/MDCLoader.h b/3rdparty/assimp/code/MDCLoader.h
deleted file mode 100644
index 4cabf09f..00000000
--- a/3rdparty/assimp/code/MDCLoader.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MDCLoader.h
- * @brief Definition of the MDC importer class.
- */
-#ifndef AI_MDCLOADER_H_INCLUDED
-#define AI_MDCLOADER_H_INCLUDED
-
-#include "../include/aiTypes.h"
-
-#include "BaseImporter.h"
-#include "MDCFileData.h"
-#include "ByteSwap.h"
-
-namespace Assimp {
-using namespace MDC;
-
-// ---------------------------------------------------------------------------
-/** Importer class to load the RtCW MDC file format
-*/
-class MDCImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- MDCImporter();
-
- /** Destructor, private as well */
- ~MDCImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Validate the header of the file
- */
- void ValidateHeader();
-
- // -------------------------------------------------------------------
- /** Validate the header of a MDC surface
- */
- void ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf);
-
-protected:
-
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Header of the MDC file */
- BE_NCONST MDC::Header* pcHeader;
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** size of the file, in bytes */
- unsigned int fileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
-
diff --git a/3rdparty/assimp/code/MDCNormalTable.h b/3rdparty/assimp/code/MDCNormalTable.h
deleted file mode 100644
index f47e97f3..00000000
--- a/3rdparty/assimp/code/MDCNormalTable.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* -----------------------------------------------------------------------------
-
-PicoModel Library
-
-Copyright (c) 2002, Randy Reddig & seaw0lf
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list
-of conditions and the following disclaimer.
-
-Redistributions in binary form must reproduce the above copyright notice, this
-list of conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution.
-
-Neither the names of the copyright holders nor the names of its contributors may
-be used to endorse or promote products derived from this software without
-specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
------------------------------------------------------------------------------ */
-
-#if (!defined MDC_NORMAL_TABLE_INCLUDED)
-#define MDC_NORMAL_TABLE_INCLUDED
-
-/* mdc decoding normal table */
-float mdcNormals[ 256 ][ 3 ] =
-{
- { 1.000000f, 0.000000f, 0.000000f },
- { 0.980785f, 0.195090f, 0.000000f },
- { 0.923880f, 0.382683f, 0.000000f },
- { 0.831470f, 0.555570f, 0.000000f },
- { 0.707107f, 0.707107f, 0.000000f },
- { 0.555570f, 0.831470f, 0.000000f },
- { 0.382683f, 0.923880f, 0.000000f },
- { 0.195090f, 0.980785f, 0.000000f },
- { -0.000000f, 1.000000f, 0.000000f },
- { -0.195090f, 0.980785f, 0.000000f },
- { -0.382683f, 0.923880f, 0.000000f },
- { -0.555570f, 0.831470f, 0.000000f },
- { -0.707107f, 0.707107f, 0.000000f },
- { -0.831470f, 0.555570f, 0.000000f },
- { -0.923880f, 0.382683f, 0.000000f },
- { -0.980785f, 0.195090f, 0.000000f },
- { -1.000000f, -0.000000f, 0.000000f },
- { -0.980785f, -0.195090f, 0.000000f },
- { -0.923880f, -0.382683f, 0.000000f },
- { -0.831470f, -0.555570f, 0.000000f },
- { -0.707107f, -0.707107f, 0.000000f },
- { -0.555570f, -0.831469f, 0.000000f },
- { -0.382684f, -0.923880f, 0.000000f },
- { -0.195090f, -0.980785f, 0.000000f },
- { 0.000000f, -1.000000f, 0.000000f },
- { 0.195090f, -0.980785f, 0.000000f },
- { 0.382684f, -0.923879f, 0.000000f },
- { 0.555570f, -0.831470f, 0.000000f },
- { 0.707107f, -0.707107f, 0.000000f },
- { 0.831470f, -0.555570f, 0.000000f },
- { 0.923880f, -0.382683f, 0.000000f },
- { 0.980785f, -0.195090f, 0.000000f },
- { 0.980785f, 0.000000f, -0.195090f },
- { 0.956195f, 0.218245f, -0.195090f },
- { 0.883657f, 0.425547f, -0.195090f },
- { 0.766809f, 0.611510f, -0.195090f },
- { 0.611510f, 0.766809f, -0.195090f },
- { 0.425547f, 0.883657f, -0.195090f },
- { 0.218245f, 0.956195f, -0.195090f },
- { -0.000000f, 0.980785f, -0.195090f },
- { -0.218245f, 0.956195f, -0.195090f },
- { -0.425547f, 0.883657f, -0.195090f },
- { -0.611510f, 0.766809f, -0.195090f },
- { -0.766809f, 0.611510f, -0.195090f },
- { -0.883657f, 0.425547f, -0.195090f },
- { -0.956195f, 0.218245f, -0.195090f },
- { -0.980785f, -0.000000f, -0.195090f },
- { -0.956195f, -0.218245f, -0.195090f },
- { -0.883657f, -0.425547f, -0.195090f },
- { -0.766809f, -0.611510f, -0.195090f },
- { -0.611510f, -0.766809f, -0.195090f },
- { -0.425547f, -0.883657f, -0.195090f },
- { -0.218245f, -0.956195f, -0.195090f },
- { 0.000000f, -0.980785f, -0.195090f },
- { 0.218245f, -0.956195f, -0.195090f },
- { 0.425547f, -0.883657f, -0.195090f },
- { 0.611510f, -0.766809f, -0.195090f },
- { 0.766809f, -0.611510f, -0.195090f },
- { 0.883657f, -0.425547f, -0.195090f },
- { 0.956195f, -0.218245f, -0.195090f },
- { 0.923880f, 0.000000f, -0.382683f },
- { 0.892399f, 0.239118f, -0.382683f },
- { 0.800103f, 0.461940f, -0.382683f },
- { 0.653281f, 0.653281f, -0.382683f },
- { 0.461940f, 0.800103f, -0.382683f },
- { 0.239118f, 0.892399f, -0.382683f },
- { -0.000000f, 0.923880f, -0.382683f },
- { -0.239118f, 0.892399f, -0.382683f },
- { -0.461940f, 0.800103f, -0.382683f },
- { -0.653281f, 0.653281f, -0.382683f },
- { -0.800103f, 0.461940f, -0.382683f },
- { -0.892399f, 0.239118f, -0.382683f },
- { -0.923880f, -0.000000f, -0.382683f },
- { -0.892399f, -0.239118f, -0.382683f },
- { -0.800103f, -0.461940f, -0.382683f },
- { -0.653282f, -0.653281f, -0.382683f },
- { -0.461940f, -0.800103f, -0.382683f },
- { -0.239118f, -0.892399f, -0.382683f },
- { 0.000000f, -0.923880f, -0.382683f },
- { 0.239118f, -0.892399f, -0.382683f },
- { 0.461940f, -0.800103f, -0.382683f },
- { 0.653281f, -0.653282f, -0.382683f },
- { 0.800103f, -0.461940f, -0.382683f },
- { 0.892399f, -0.239117f, -0.382683f },
- { 0.831470f, 0.000000f, -0.555570f },
- { 0.790775f, 0.256938f, -0.555570f },
- { 0.672673f, 0.488726f, -0.555570f },
- { 0.488726f, 0.672673f, -0.555570f },
- { 0.256938f, 0.790775f, -0.555570f },
- { -0.000000f, 0.831470f, -0.555570f },
- { -0.256938f, 0.790775f, -0.555570f },
- { -0.488726f, 0.672673f, -0.555570f },
- { -0.672673f, 0.488726f, -0.555570f },
- { -0.790775f, 0.256938f, -0.555570f },
- { -0.831470f, -0.000000f, -0.555570f },
- { -0.790775f, -0.256938f, -0.555570f },
- { -0.672673f, -0.488726f, -0.555570f },
- { -0.488725f, -0.672673f, -0.555570f },
- { -0.256938f, -0.790775f, -0.555570f },
- { 0.000000f, -0.831470f, -0.555570f },
- { 0.256938f, -0.790775f, -0.555570f },
- { 0.488725f, -0.672673f, -0.555570f },
- { 0.672673f, -0.488726f, -0.555570f },
- { 0.790775f, -0.256938f, -0.555570f },
- { 0.707107f, 0.000000f, -0.707107f },
- { 0.653281f, 0.270598f, -0.707107f },
- { 0.500000f, 0.500000f, -0.707107f },
- { 0.270598f, 0.653281f, -0.707107f },
- { -0.000000f, 0.707107f, -0.707107f },
- { -0.270598f, 0.653282f, -0.707107f },
- { -0.500000f, 0.500000f, -0.707107f },
- { -0.653281f, 0.270598f, -0.707107f },
- { -0.707107f, -0.000000f, -0.707107f },
- { -0.653281f, -0.270598f, -0.707107f },
- { -0.500000f, -0.500000f, -0.707107f },
- { -0.270598f, -0.653281f, -0.707107f },
- { 0.000000f, -0.707107f, -0.707107f },
- { 0.270598f, -0.653281f, -0.707107f },
- { 0.500000f, -0.500000f, -0.707107f },
- { 0.653282f, -0.270598f, -0.707107f },
- { 0.555570f, 0.000000f, -0.831470f },
- { 0.481138f, 0.277785f, -0.831470f },
- { 0.277785f, 0.481138f, -0.831470f },
- { -0.000000f, 0.555570f, -0.831470f },
- { -0.277785f, 0.481138f, -0.831470f },
- { -0.481138f, 0.277785f, -0.831470f },
- { -0.555570f, -0.000000f, -0.831470f },
- { -0.481138f, -0.277785f, -0.831470f },
- { -0.277785f, -0.481138f, -0.831470f },
- { 0.000000f, -0.555570f, -0.831470f },
- { 0.277785f, -0.481138f, -0.831470f },
- { 0.481138f, -0.277785f, -0.831470f },
- { 0.382683f, 0.000000f, -0.923880f },
- { 0.270598f, 0.270598f, -0.923880f },
- { -0.000000f, 0.382683f, -0.923880f },
- { -0.270598f, 0.270598f, -0.923880f },
- { -0.382683f, -0.000000f, -0.923880f },
- { -0.270598f, -0.270598f, -0.923880f },
- { 0.000000f, -0.382683f, -0.923880f },
- { 0.270598f, -0.270598f, -0.923880f },
- { 0.195090f, 0.000000f, -0.980785f },
- { -0.000000f, 0.195090f, -0.980785f },
- { -0.195090f, -0.000000f, -0.980785f },
- { 0.000000f, -0.195090f, -0.980785f },
- { 0.980785f, 0.000000f, 0.195090f },
- { 0.956195f, 0.218245f, 0.195090f },
- { 0.883657f, 0.425547f, 0.195090f },
- { 0.766809f, 0.611510f, 0.195090f },
- { 0.611510f, 0.766809f, 0.195090f },
- { 0.425547f, 0.883657f, 0.195090f },
- { 0.218245f, 0.956195f, 0.195090f },
- { -0.000000f, 0.980785f, 0.195090f },
- { -0.218245f, 0.956195f, 0.195090f },
- { -0.425547f, 0.883657f, 0.195090f },
- { -0.611510f, 0.766809f, 0.195090f },
- { -0.766809f, 0.611510f, 0.195090f },
- { -0.883657f, 0.425547f, 0.195090f },
- { -0.956195f, 0.218245f, 0.195090f },
- { -0.980785f, -0.000000f, 0.195090f },
- { -0.956195f, -0.218245f, 0.195090f },
- { -0.883657f, -0.425547f, 0.195090f },
- { -0.766809f, -0.611510f, 0.195090f },
- { -0.611510f, -0.766809f, 0.195090f },
- { -0.425547f, -0.883657f, 0.195090f },
- { -0.218245f, -0.956195f, 0.195090f },
- { 0.000000f, -0.980785f, 0.195090f },
- { 0.218245f, -0.956195f, 0.195090f },
- { 0.425547f, -0.883657f, 0.195090f },
- { 0.611510f, -0.766809f, 0.195090f },
- { 0.766809f, -0.611510f, 0.195090f },
- { 0.883657f, -0.425547f, 0.195090f },
- { 0.956195f, -0.218245f, 0.195090f },
- { 0.923880f, 0.000000f, 0.382683f },
- { 0.892399f, 0.239118f, 0.382683f },
- { 0.800103f, 0.461940f, 0.382683f },
- { 0.653281f, 0.653281f, 0.382683f },
- { 0.461940f, 0.800103f, 0.382683f },
- { 0.239118f, 0.892399f, 0.382683f },
- { -0.000000f, 0.923880f, 0.382683f },
- { -0.239118f, 0.892399f, 0.382683f },
- { -0.461940f, 0.800103f, 0.382683f },
- { -0.653281f, 0.653281f, 0.382683f },
- { -0.800103f, 0.461940f, 0.382683f },
- { -0.892399f, 0.239118f, 0.382683f },
- { -0.923880f, -0.000000f, 0.382683f },
- { -0.892399f, -0.239118f, 0.382683f },
- { -0.800103f, -0.461940f, 0.382683f },
- { -0.653282f, -0.653281f, 0.382683f },
- { -0.461940f, -0.800103f, 0.382683f },
- { -0.239118f, -0.892399f, 0.382683f },
- { 0.000000f, -0.923880f, 0.382683f },
- { 0.239118f, -0.892399f, 0.382683f },
- { 0.461940f, -0.800103f, 0.382683f },
- { 0.653281f, -0.653282f, 0.382683f },
- { 0.800103f, -0.461940f, 0.382683f },
- { 0.892399f, -0.239117f, 0.382683f },
- { 0.831470f, 0.000000f, 0.555570f },
- { 0.790775f, 0.256938f, 0.555570f },
- { 0.672673f, 0.488726f, 0.555570f },
- { 0.488726f, 0.672673f, 0.555570f },
- { 0.256938f, 0.790775f, 0.555570f },
- { -0.000000f, 0.831470f, 0.555570f },
- { -0.256938f, 0.790775f, 0.555570f },
- { -0.488726f, 0.672673f, 0.555570f },
- { -0.672673f, 0.488726f, 0.555570f },
- { -0.790775f, 0.256938f, 0.555570f },
- { -0.831470f, -0.000000f, 0.555570f },
- { -0.790775f, -0.256938f, 0.555570f },
- { -0.672673f, -0.488726f, 0.555570f },
- { -0.488725f, -0.672673f, 0.555570f },
- { -0.256938f, -0.790775f, 0.555570f },
- { 0.000000f, -0.831470f, 0.555570f },
- { 0.256938f, -0.790775f, 0.555570f },
- { 0.488725f, -0.672673f, 0.555570f },
- { 0.672673f, -0.488726f, 0.555570f },
- { 0.790775f, -0.256938f, 0.555570f },
- { 0.707107f, 0.000000f, 0.707107f },
- { 0.653281f, 0.270598f, 0.707107f },
- { 0.500000f, 0.500000f, 0.707107f },
- { 0.270598f, 0.653281f, 0.707107f },
- { -0.000000f, 0.707107f, 0.707107f },
- { -0.270598f, 0.653282f, 0.707107f },
- { -0.500000f, 0.500000f, 0.707107f },
- { -0.653281f, 0.270598f, 0.707107f },
- { -0.707107f, -0.000000f, 0.707107f },
- { -0.653281f, -0.270598f, 0.707107f },
- { -0.500000f, -0.500000f, 0.707107f },
- { -0.270598f, -0.653281f, 0.707107f },
- { 0.000000f, -0.707107f, 0.707107f },
- { 0.270598f, -0.653281f, 0.707107f },
- { 0.500000f, -0.500000f, 0.707107f },
- { 0.653282f, -0.270598f, 0.707107f },
- { 0.555570f, 0.000000f, 0.831470f },
- { 0.481138f, 0.277785f, 0.831470f },
- { 0.277785f, 0.481138f, 0.831470f },
- { -0.000000f, 0.555570f, 0.831470f },
- { -0.277785f, 0.481138f, 0.831470f },
- { -0.481138f, 0.277785f, 0.831470f },
- { -0.555570f, -0.000000f, 0.831470f },
- { -0.481138f, -0.277785f, 0.831470f },
- { -0.277785f, -0.481138f, 0.831470f },
- { 0.000000f, -0.555570f, 0.831470f },
- { 0.277785f, -0.481138f, 0.831470f },
- { 0.481138f, -0.277785f, 0.831470f },
- { 0.382683f, 0.000000f, 0.923880f },
- { 0.270598f, 0.270598f, 0.923880f },
- { -0.000000f, 0.382683f, 0.923880f },
- { -0.270598f, 0.270598f, 0.923880f },
- { -0.382683f, -0.000000f, 0.923880f },
- { -0.270598f, -0.270598f, 0.923880f },
- { 0.000000f, -0.382683f, 0.923880f },
- { 0.270598f, -0.270598f, 0.923880f },
- { 0.195090f, 0.000000f, 0.980785f },
- { -0.000000f, 0.195090f, 0.980785f },
- { -0.195090f, -0.000000f, 0.980785f },
- { 0.000000f, -0.195090f, 0.980785f }
-};
-
-#endif // !! MDC_NORMAL_TABLE_INCLUDED
diff --git a/3rdparty/assimp/code/MDLDefaultColorMap.h b/3rdparty/assimp/code/MDLDefaultColorMap.h
deleted file mode 100644
index a40da826..00000000
--- a/3rdparty/assimp/code/MDLDefaultColorMap.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines the default color map used for Quake 1 model textures
- *
- * The lib tries to load colormap.lmp from the model's directory.
- * This table is only used when required.
- */
-
-#ifndef AI_MDL_DEFAULTLMP_H_INC
-#define AI_MDL_DEFAULTLMP_H_INC
-
-const unsigned char g_aclrDefaultColorMap[256][3] = {
-{ 0, 0, 0}, { 15, 15, 15}, { 31, 31, 31}, { 47, 47, 47},
-{ 63, 63, 63}, { 75, 75, 75}, { 91, 91, 91}, {107, 107, 107},
-{123, 123, 123}, {139, 139, 139}, {155, 155, 155}, {171, 171, 171},
-{187, 187, 187}, {203, 203, 203}, {219, 219, 219}, {235, 235, 235},
-{ 15, 11, 7}, { 23, 15, 11}, { 31, 23, 11}, { 39, 27, 15},
-{ 47, 35, 19}, { 55, 43, 23}, { 63, 47, 23}, { 75, 55, 27},
-{ 83, 59, 27}, { 91, 67, 31}, { 99, 75, 31}, {107, 83, 31},
-{115, 87, 31}, {123, 95, 35}, {131, 103, 35}, {143, 111, 35},
-{ 11, 11, 15}, { 19, 19, 27}, { 27, 27, 39}, { 39, 39, 51},
-{ 47, 47, 63}, { 55, 55, 75}, { 63, 63, 87}, { 71, 71, 103},
-{ 79, 79, 115}, { 91, 91, 127}, { 99, 99, 139}, {107, 107, 151},
-{115, 115, 163}, {123, 123, 175}, {131, 131, 187}, {139, 139, 203},
-{ 0, 0, 0}, { 7, 7, 0}, { 11, 11, 0}, { 19, 19, 0},
-{ 27, 27, 0}, { 35, 35, 0}, { 43, 43, 7}, { 47, 47, 7},
-{ 55, 55, 7}, { 63, 63, 7}, { 71, 71, 7}, { 75, 75, 11},
-{ 83, 83, 11}, { 91, 91, 11}, { 99, 99, 11}, {107, 107, 15},
-{ 7, 0, 0}, { 15, 0, 0}, { 23, 0, 0}, { 31, 0, 0},
-{ 39, 0, 0}, { 47, 0, 0}, { 55, 0, 0}, { 63, 0, 0},
-{ 71, 0, 0}, { 79, 0, 0}, { 87, 0, 0}, { 95, 0, 0},
-{103, 0, 0}, {111, 0, 0}, {119, 0, 0}, {127, 0, 0},
-{ 19, 19, 0}, { 27, 27, 0}, { 35, 35, 0}, { 47, 43, 0},
-{ 55, 47, 0}, { 67, 55, 0}, { 75, 59, 7}, { 87, 67, 7},
-{ 95, 71, 7}, {107, 75, 11}, {119, 83, 15}, {131, 87, 19},
-{139, 91, 19}, {151, 95, 27}, {163, 99, 31}, {175, 103, 35},
-{ 35, 19, 7}, { 47, 23, 11}, { 59, 31, 15}, { 75, 35, 19},
-{ 87, 43, 23}, { 99, 47, 31}, {115, 55, 35}, {127, 59, 43},
-{143, 67, 51}, {159, 79, 51}, {175, 99, 47}, {191, 119, 47},
-{207, 143, 43}, {223, 171, 39}, {239, 203, 31}, {255, 243, 27},
-{ 11, 7, 0}, { 27, 19, 0}, { 43, 35, 15}, { 55, 43, 19},
-{ 71, 51, 27}, { 83, 55, 35}, { 99, 63, 43}, {111, 71, 51},
-{127, 83, 63}, {139, 95, 71}, {155, 107, 83}, {167, 123, 95},
-{183, 135, 107}, {195, 147, 123}, {211, 163, 139}, {227, 179, 151},
-{171, 139, 163}, {159, 127, 151}, {147, 115, 135}, {139, 103, 123},
-{127, 91, 111}, {119, 83, 99}, {107, 75, 87}, { 95, 63, 75},
-{ 87, 55, 67}, { 75, 47, 55}, { 67, 39, 47}, { 55, 31, 35},
-{ 43, 23, 27}, { 35, 19, 19}, { 23, 11, 11}, { 15, 7, 7},
-{187, 115, 159}, {175, 107, 143}, {163, 95, 131}, {151, 87, 119},
-{139, 79, 107}, {127, 75, 95}, {115, 67, 83}, {107, 59, 75},
-{ 95, 51, 63}, { 83, 43, 55}, { 71, 35, 43}, { 59, 31, 35},
-{ 47, 23, 27}, { 35, 19, 19}, { 23, 11, 11}, { 15, 7, 7},
-{219, 195, 187}, {203, 179, 167}, {191, 163, 155}, {175, 151, 139},
-{163, 135, 123}, {151, 123, 111}, {135, 111, 95}, {123, 99, 83},
-{107, 87, 71}, { 95, 75, 59}, { 83, 63, 51}, { 67, 51, 39},
-{ 55, 43, 31}, { 39, 31, 23}, { 27, 19, 15}, { 15, 11, 7},
-{111, 131, 123}, {103, 123, 111}, { 95, 115, 103}, { 87, 107, 95},
-{ 79, 99, 87}, { 71, 91, 79}, { 63, 83, 71}, { 55, 75, 63},
-{ 47, 67, 55}, { 43, 59, 47}, { 35, 51, 39}, { 31, 43, 31},
-{ 23, 35, 23}, { 15, 27, 19}, { 11, 19, 11}, { 7, 11, 7},
-{255, 243, 27}, {239, 223, 23}, {219, 203, 19}, {203, 183, 15},
-{187, 167, 15}, {171, 151, 11}, {155, 131, 7}, {139, 115, 7},
-{123, 99, 7}, {107, 83, 0}, { 91, 71, 0}, { 75, 55, 0},
-{ 59, 43, 0}, { 43, 31, 0}, { 27, 15, 0}, { 11, 7, 0},
-{ 0, 0, 255}, { 11, 11, 239}, { 19, 19, 223}, { 27, 27, 207},
-{ 35, 35, 191}, { 43, 43, 175}, { 47, 47, 159}, { 47, 47, 143},
-{ 47, 47, 127}, { 47, 47, 111}, { 47, 47, 95}, { 43, 43, 79},
-{ 35, 35, 63}, { 27, 27, 47}, { 19, 19, 31}, { 11, 11, 15},
-{ 43, 0, 0}, { 59, 0, 0}, { 75, 7, 0}, { 95, 7, 0},
-{111, 15, 0}, {127, 23, 7}, {147, 31, 7}, {163, 39, 11},
-{183, 51, 15}, {195, 75, 27}, {207, 99, 43}, {219, 127, 59},
-{227, 151, 79}, {231, 171, 95}, {239, 191, 119}, {247, 211, 139},
-{167, 123, 59}, {183, 155, 55}, {199, 195, 55}, {231, 227, 87},
-{127, 191, 255}, {171, 231, 255}, {215, 255, 255}, {103, 0, 0},
-{139, 0, 0}, {179, 0, 0}, {215, 0, 0}, {255, 0, 0},
-{255, 243, 147}, {255, 247, 199}, {255, 255, 255}, {159, 91, 83} };
-
-
-#endif // !! AI_MDL_DEFAULTLMP_H_INC
diff --git a/3rdparty/assimp/code/MDLFileData.h b/3rdparty/assimp/code/MDLFileData.h
deleted file mode 100644
index 098cb8dc..00000000
--- a/3rdparty/assimp/code/MDLFileData.h
+++ /dev/null
@@ -1,959 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/**
- * @file MDLFileData.h
- * @brief Definition of in-memory structures for the MDL file format.
- *
- * The specification has been taken from various sources on the internet.
- * - http://tfc.duke.free.fr/coding/mdl-specs-en.html
- * - Conitec's MED SDK
- * - Many quite long HEX-editor sessions
- */
-
-#ifndef AI_MDLFILEHELPER_H_INC
-#define AI_MDLFILEHELPER_H_INC
-
-#include "./../include/Compiler/pushpack1.h"
-
-namespace Assimp {
-namespace MDL {
-
-// -------------------------------------------------------------------------------------
-// to make it easier for us, we test the magic word against both "endianesses"
-
-// magic bytes used in Quake 1 MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDPO")
-#define AI_MDL_MAGIC_NUMBER_LE AI_MAKE_MAGIC("OPDI")
-
-// magic bytes used in GameStudio A<very low> MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS3 AI_MAKE_MAGIC("MDL2")
-#define AI_MDL_MAGIC_NUMBER_LE_GS3 AI_MAKE_MAGIC("2LDM")
-
-// magic bytes used in GameStudio A4 MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS4 AI_MAKE_MAGIC("MDL3")
-#define AI_MDL_MAGIC_NUMBER_LE_GS4 AI_MAKE_MAGIC("3LDM")
-
-// magic bytes used in GameStudio A5+ MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS5a AI_MAKE_MAGIC("MDL4")
-#define AI_MDL_MAGIC_NUMBER_LE_GS5a AI_MAKE_MAGIC("4LDM")
-#define AI_MDL_MAGIC_NUMBER_BE_GS5b AI_MAKE_MAGIC("MDL5")
-#define AI_MDL_MAGIC_NUMBER_LE_GS5b AI_MAKE_MAGIC("5LDM")
-
-// magic bytes used in GameStudio A7+ MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
-#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
-
-
-// common limitations for Quake1 meshes. The loader does not check them,
-// (however it warns) but models should not exceed these limits.
-#if (!defined AI_MDL_VERSION)
-# define AI_MDL_VERSION 6
-#endif
-#if (!defined AI_MDL_MAX_FRAMES)
-# define AI_MDL_MAX_FRAMES 256
-#endif
-#if (!defined AI_MDL_MAX_UVS)
-# define AI_MDL_MAX_UVS 1024
-#endif
-#if (!defined AI_MDL_MAX_VERTS)
-# define AI_MDL_MAX_VERTS 1024
-#endif
-#if (!defined AI_MDL_MAX_TRIANGLES)
-# define AI_MDL_MAX_TRIANGLES 2048
-#endif
-
-// material key that is set for dummy materials that are
-// just referencing another material
-#if (!defined AI_MDL7_REFERRER_MATERIAL)
-# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
-#endif
-
-// -------------------------------------------------------------------------------------
-/** \struct Header
- * \brief Data structure for the MDL main header
- */
-struct Header
-{
- //! magic number: "IDPO"
- uint32_t ident;
-
- //! version number: 6
- int32_t version;
-
- //! scale factors for each axis
- aiVector3D scale;
-
- //! translation factors for each axis
- aiVector3D translate;
-
- //! bounding radius of the mesh
- float boundingradius;
-
- //! Position of the viewer's exe. Ignored
- aiVector3D vEyePos;
-
- //! Number of textures
- int32_t num_skins;
-
- //! Texture width in pixels
- int32_t skinwidth;
-
- //! Texture height in pixels
- int32_t skinheight;
-
- //! Number of vertices contained in the file
- int32_t num_verts;
-
- //! Number of triangles contained in the file
- int32_t num_tris;
-
- //! Number of frames contained in the file
- int32_t num_frames;
-
- //! 0 = synchron, 1 = random . Ignored
- //! (MDLn formats: number of texture coordinates)
- int32_t synctype;
-
- //! State flag
- int32_t flags;
-
- //! Could be the total size of the file (and not a float)
- float size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Header_MDL7
- * \brief Data structure for the MDL 7 main header
- */
-struct Header_MDL7
-{
- //! magic number: "MDL7"
- char ident[4];
-
- //! Version number. Ignored
- int32_t version;
-
- //! Number of bones in file
- uint32_t bones_num;
-
- //! Number of groups in file
- uint32_t groups_num;
-
- //! Size of data in the file
- uint32_t data_size;
-
- //! Ignored. Used to store entity specific information
- int32_t entlump_size;
-
- //! Ignored. Used to store MED related data
- int32_t medlump_size;
-
- //! Size of the Bone_MDL7 data structure used in the file
- uint16_t bone_stc_size;
-
- //! Size of the Skin_MDL 7 data structure used in the file
- uint16_t skin_stc_size;
-
- //! Size of a single color (e.g. in a material)
- uint16_t colorvalue_stc_size;
-
- //! Size of the Material_MDL7 data structure used in the file
- uint16_t material_stc_size;
-
- //! Size of a texture coordinate set in the file
- uint16_t skinpoint_stc_size;
-
- //! Size of a triangle in the file
- uint16_t triangle_stc_size;
-
- //! Size of a normal vertex in the file
- uint16_t mainvertex_stc_size;
-
- //! Size of a per-frame animated vertex in the file
- //! (this is not supported)
- uint16_t framevertex_stc_size;
-
- //! Size of a bone animation matrix
- uint16_t bonetrans_stc_size;
-
- //! Size of the Frame_MDL7 data structure used in the file
- uint16_t frame_stc_size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Bone_MDL7
- * \brief Data structure for a bone in a MDL7 file
- */
-struct Bone_MDL7
-{
- //! Index of the parent bone of *this* bone. 0xffff means:
- //! "hey, I have no parent, I'm an orphan"
- uint16_t parent_index;
- uint8_t _unused_[2];
-
- //! Relative position of the bone (relative to the
- //! parent bone)
- float x,y,z;
-
- //! Optional name of the bone
- char name[1 /* DUMMY SIZE */];
-} PACK_STRUCT;
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
-#endif
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS (16 + 32)
-#endif
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE (16)
-#endif
-
-#if (!defined AI_MDL7_MAX_GROUPNAMESIZE)
-# define AI_MDL7_MAX_GROUPNAMESIZE 16
-#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
-
-// -------------------------------------------------------------------------------------
-/** \struct Group_MDL7
- * \brief Group in a MDL7 file
- */
-struct Group_MDL7
-{
- //! = '1' -> triangle based Mesh
- unsigned char typ;
-
- int8_t deformers;
- int8_t max_weights;
- int8_t _unused_;
-
- //! size of data for this group in bytes ( MD7_GROUP stc. included).
- int32_t groupdata_size;
- char name[AI_MDL7_MAX_GROUPNAMESIZE];
-
- //! Number of skins
- int32_t numskins;
-
- //! Number of texture coordinates
- int32_t num_stpts;
-
- //! Number of triangles
- int32_t numtris;
-
- //! Number of vertices
- int32_t numverts;
-
- //! Number of frames
- int32_t numframes;
-} PACK_STRUCT;
-
-#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
-#define AI_MDL7_SKINTYPE_MATERIAL 0x10
-#define AI_MDL7_SKINTYPE_MATERIAL_ASCDEF 0x20
-#define AI_MDL7_SKINTYPE_RGBFLAG 0x80
-
-#if (!defined AI_MDL7_MAX_BONENAMESIZE)
-# define AI_MDL7_MAX_BONENAMESIZE 20
-#endif // !! AI_MDL7_MAX_BONENAMESIZE
-
-// -------------------------------------------------------------------------------------
-/** \struct Deformer_MDL7
- * \brief Deformer in a MDL7 file
- */
-struct Deformer_MDL7
-{
- int8_t deformer_version; // 0
- int8_t deformer_typ; // 0 - bones
- int8_t _unused_[2];
- int32_t group_index;
- int32_t elements;
- int32_t deformerdata_size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct DeformerElement_MDL7
- * \brief Deformer element in a MDL7 file
- */
-struct DeformerElement_MDL7
-{
- //! bei deformer_typ==0 (==bones) element_index == bone index
- int32_t element_index;
- char element_name[AI_MDL7_MAX_BONENAMESIZE];
- int32_t weights;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct DeformerWeight_MDL7
- * \brief Deformer weight in a MDL7 file
- */
-struct DeformerWeight_MDL7
-{
- //! for deformer_typ==0 (==bones) index == vertex index
- int32_t index;
- float weight;
-} PACK_STRUCT;
-
-
-// don't know why this was in the original headers ...
-typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
-
-// -------------------------------------------------------------------------------------
-/** \struct ColorValue_MDL7
- * \brief Data structure for a color value in a MDL7 file
- */
-struct ColorValue_MDL7
-{
- float r,g,b,a;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Material_MDL7
- * \brief Data structure for a Material in a MDL7 file
- */
-struct Material_MDL7
-{
- //! Diffuse base color of the material
- ColorValue_MDL7 Diffuse;
-
- //! Ambient base color of the material
- ColorValue_MDL7 Ambient;
-
- //! Specular base color of the material
- ColorValue_MDL7 Specular;
-
- //! Emissive base color of the material
- ColorValue_MDL7 Emissive;
-
- //! Phong power
- float Power;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Skin
- * \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
- */
-struct Skin
-{
- //! 0 = single (Skin), 1 = group (GroupSkin)
- //! For MDL3-5: Defines the type of the skin and there
- //! fore the size of the data to skip:
- //-------------------------------------------------------
- //! 2 for 565 RGB,
- //! 3 for 4444 ARGB,
- //! 10 for 565 mipmapped,
- //! 11 for 4444 mipmapped (bpp = 2),
- //! 12 for 888 RGB mipmapped (bpp = 3),
- //! 13 for 8888 ARGB mipmapped (bpp = 4)
- //-------------------------------------------------------
- int32_t group;
-
- //! Texture data
- uint8_t *data;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Skin
- * \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
- * \see Skin
- */
-struct Skin_MDL5
-{
- int32_t size, width, height;
- uint8_t *data;
-} PACK_STRUCT;
-
-// maximum length of texture file name
-#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
-# define AI_MDL7_MAX_TEXNAMESIZE 0x10
-#endif
-
-// ---------------------------------------------------------------------------
-/** \struct Skin_MDL7
- * \brief Skin data structure #3 - used by MDL7 and HMP7
- */
-struct Skin_MDL7
-{
- uint8_t typ;
- int8_t _unused_[3];
- int32_t width;
- int32_t height;
- char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct RGB565
- * \brief Data structure for a RGB565 pixel in a texture
- */
-struct RGB565
-{
- uint16_t r : 5;
- uint16_t g : 6;
- uint16_t b : 5;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct ARGB4
- * \brief Data structure for a ARGB4444 pixel in a texture
- */
-struct ARGB4
-{
- uint16_t a : 4;
- uint16_t r : 4;
- uint16_t g : 4;
- uint16_t b : 4;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct GroupSkin
- * \brief Skin data structure #2 (group of pictures)
- */
-struct GroupSkin
-{
- //! 0 = single (Skin), 1 = group (GroupSkin)
- int32_t group;
-
- //! Number of images
- int32_t nb;
-
- //! Time for each image
- float *time;
-
- //! Data of each image
- uint8_t **data;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord
- * \brief Texture coordinate data structure used by the Quake1 MDL format
- */
-struct TexCoord
-{
- //! Is the vertex on the noundary between front and back piece?
- int32_t onseam;
-
- //! Texture coordinate in the tx direction
- int32_t s;
-
- //! Texture coordinate in the ty direction
- int32_t t;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord_MDL3
- * \brief Data structure for an UV coordinate in the 3DGS MDL3 format
- */
-struct TexCoord_MDL3
-{
- //! position, horizontally in range 0..skinwidth-1
- int16_t u;
-
- //! position, vertically in range 0..skinheight-1
- int16_t v;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord_MDL7
- * \brief Data structure for an UV coordinate in the 3DGS MDL7 format
- */
-struct TexCoord_MDL7
-{
- //! position, horizontally in range 0..1
- float u;
-
- //! position, vertically in range 0..1
- float v;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct SkinSet_MDL7
- * \brief Skin set data structure for the 3DGS MDL7 format
- * MDL7 references UV coordinates per face via an index list.
- * This allows the use of multiple skins per face with just one
- * UV coordinate set.
- */
-struct SkinSet_MDL7
-{
- //! Index into the UV coordinate list
- uint16_t st_index[3]; // size 6
-
- //! Material index
- int32_t material; // size 4
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle
- * \brief Triangle data structure for the Quake1 MDL format
- */
-struct Triangle
-{
- //! 0 = backface, 1 = frontface
- int32_t facesfront;
-
- //! Vertex indices
- int32_t vertex[3];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle_MDL3
- * \brief Triangle data structure for the 3DGS MDL3 format
- */
-struct Triangle_MDL3
-{
- //! Index of 3 3D vertices in range 0..numverts
- uint16_t index_xyz[3];
-
- //! Index of 3 skin vertices in range 0..numskinverts
- uint16_t index_uv[3];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle_MDL7
- * \brief Triangle data structure for the 3DGS MDL7 format
- */
-struct Triangle_MDL7
-{
- //! Vertex indices
- uint16_t v_index[3]; // size 6
-
- //! Two skinsets. The second will be used for multi-texturing
- SkinSet_MDL7 skinsets[2];
-} PACK_STRUCT;
-
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
-# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
-#endif
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX)
-# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX (6+sizeof(SkinSet_MDL7))
-#endif
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
-# define AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV (6+2*sizeof(SkinSet_MDL7))
-#endif
-
-// Helper constants for Triangle::facesfront
-#if (!defined AI_MDL_BACKFACE)
-# define AI_MDL_BACKFACE 0x0
-#endif
-#if (!defined AI_MDL_FRONTFACE)
-# define AI_MDL_FRONTFACE 0x1
-#endif
-
-// -------------------------------------------------------------------------------------
-/** \struct Vertex
- * \brief Vertex data structure
- */
-struct Vertex
-{
- uint8_t v[3];
- uint8_t normalIndex;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-struct Vertex_MDL4
-{
- uint16_t v[3];
- uint8_t normalIndex;
- uint8_t unused;
-} PACK_STRUCT;
-
-#define AI_MDL7_FRAMEVERTEX120503_STCSIZE 16
-#define AI_MDL7_FRAMEVERTEX030305_STCSIZE 26
-
-// -------------------------------------------------------------------------------------
-/** \struct Vertex_MDL7
- * \brief Vertex data structure used in MDL7 files
- */
-struct Vertex_MDL7
-{
- float x,y,z;
- uint16_t vertindex; // = bone index
- union {
- uint8_t norm162index;
- float norm[3];
- };
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct BoneTransform_MDL7
- * \brief bone transformation matrix structure used in MDL7 files
- */
-struct BoneTransform_MDL7
-{
- //! 4*3
- float m [4*4];
-
- //! the index of this vertex, 0.. header::bones_num - 1
- uint16_t bone_index;
-
- //! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
- //! THIS STUPID FILE FORMAT!
- int8_t _unused_[2];
-} PACK_STRUCT;
-
-
-#define AI_MDL7_MAX_FRAMENAMESIZE 16
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Frame_MDL7
- * \brief Frame data structure used by MDL7 files
- */
-struct Frame_MDL7
-{
- char frame_name[AI_MDL7_MAX_FRAMENAMESIZE];
- uint32_t vertices_count;
- uint32_t transmatrix_count;
-};
-
-
-// -------------------------------------------------------------------------------------
-/** \struct SimpleFrame
- * \brief Data structure for a simple frame
- */
-struct SimpleFrame
-{
- //! Minimum vertex of the bounding box
- Vertex bboxmin;
-
- //! Maximum vertex of the bounding box
- Vertex bboxmax;
-
- //! Name of the frame
- char name[16];
-
- //! Vertex list of the frame
- Vertex *verts;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Frame
- * \brief Model frame data structure
- */
-struct Frame
-{
- //! 0 = simple frame, !0 = group frame
- int32_t type;
-
- //! Frame data
- SimpleFrame frame;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-struct SimpleFrame_MDLn_SP
-{
- //! Minimum vertex of the bounding box
- Vertex_MDL4 bboxmin;
-
- //! Maximum vertex of the bounding box
- Vertex_MDL4 bboxmax;
-
- //! Name of the frame
- char name[16];
-
- //! Vertex list of the frame
- Vertex_MDL4 *verts;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct GroupFrame
- * \brief Data structure for a group of frames
- */
-struct GroupFrame
-{
- //! 0 = simple frame, !0 = group frame
- int32_t type;
-
- //! Minimum vertex for all single frames
- Vertex min;
-
- //! Maximum vertex for all single frames
- Vertex max;
-
- //! Time for all single frames
- float *time;
-
- //! List of single frames
- SimpleFrame *frames;
-} PACK_STRUCT;
-
-#include "./../include/Compiler/poppack1.h"
-
-// -------------------------------------------------------------------------------------
-/** \struct IntFace_MDL7
- * \brief Internal data structure to temporarily represent a face
- */
-struct IntFace_MDL7
-{
- // provide a constructor for our own convenience
- IntFace_MDL7()
- {
- // set everything to zero
- mIndices[0] = mIndices[1] = mIndices[2] = 0;
- iMatIndex[0] = iMatIndex[1] = 0;
- }
-
- //! Vertex indices
- uint32_t mIndices[3];
-
- //! Material index (maximally two channels, which are joined later)
- unsigned int iMatIndex[2];
-};
-
-// -------------------------------------------------------------------------------------
-/** \struct IntMaterial_MDL7
- * \brief Internal data structure to temporarily represent a material
- * which has been created from two single materials along with the
- * original material indices.
- */
-struct IntMaterial_MDL7
-{
- // provide a constructor for our own convenience
- IntMaterial_MDL7()
- {
- pcMat = NULL;
- iOldMatIndices[0] = iOldMatIndices[1] = 0;
- }
-
- //! Material instance
- MaterialHelper* pcMat;
-
- //! Old material indices
- unsigned int iOldMatIndices[2];
-};
-
-// -------------------------------------------------------------------------------------
-/** \struct IntBone_MDL7
- * \brief Internal data structure to represent a bone in a MDL7 file with
- * all of its animation channels assigned to it.
- */
-struct IntBone_MDL7 : aiBone
-{
- //! Default constructor
- IntBone_MDL7() : iParent (0xffff)
- {
- pkeyPositions.reserve(30);
- pkeyScalings.reserve(30);
- pkeyRotations.reserve(30);
- }
-
- //! Parent bone of the bone
- uint64_t iParent;
-
- //! Relative position of the bone
- aiVector3D vPosition;
-
- //! Array of position keys
- std::vector<aiVectorKey> pkeyPositions;
-
- //! Array of scaling keys
- std::vector<aiVectorKey> pkeyScalings;
-
- //! Array of rotation keys
- std::vector<aiQuatKey> pkeyRotations;
-};
-
-// -------------------------------------------------------------------------------------
-//! Describes a MDL7 frame
-struct IntFrameInfo_MDL7
-{
- //! Construction from an existing frame header
- IntFrameInfo_MDL7(BE_NCONST MDL::Frame_MDL7* _pcFrame,unsigned int _iIndex)
- : iIndex(_iIndex)
- , pcFrame(_pcFrame)
- {}
-
- //! Index of the frame
- unsigned int iIndex;
-
- //! Points to the header of the frame
- BE_NCONST MDL::Frame_MDL7* pcFrame;
-};
-
-// -------------------------------------------------------------------------------------
-//! Describes a MDL7 mesh group
-struct IntGroupInfo_MDL7
-{
- //! Default constructor
- IntGroupInfo_MDL7()
- : iIndex(0)
- , pcGroup(NULL)
- , pcGroupUVs(NULL)
- , pcGroupTris(NULL)
- , pcGroupVerts(NULL)
- {}
-
- //! Construction from an existing group header
- IntGroupInfo_MDL7(BE_NCONST MDL::Group_MDL7* _pcGroup, unsigned int _iIndex)
- : iIndex(_iIndex)
- , pcGroup(_pcGroup)
- {}
-
- //! Index of the group
- unsigned int iIndex;
-
- //! Points to the header of the group
- BE_NCONST MDL::Group_MDL7* pcGroup;
-
- //! Points to the beginning of the uv coordinate section
- BE_NCONST MDL::TexCoord_MDL7* pcGroupUVs;
-
- //! Points to the beginning of the triangle section
- BE_NCONST MDL::Triangle_MDL7* pcGroupTris;
-
- //! Points to the beginning of the vertex section
- BE_NCONST MDL::Vertex_MDL7* pcGroupVerts;
-};
-
-// -------------------------------------------------------------------------------------
-//! Holds the data that belongs to a MDL7 mesh group
-struct IntGroupData_MDL7
-{
- IntGroupData_MDL7()
- : pcFaces(NULL), bNeed2UV(false)
- {}
-
- //! Array of faces that belong to the group
- MDL::IntFace_MDL7* pcFaces;
-
- //! Array of vertex positions
- std::vector<aiVector3D> vPositions;
-
- //! Array of vertex normals
- std::vector<aiVector3D> vNormals;
-
- //! Array of bones indices
- std::vector<unsigned int> aiBones;
-
- //! First UV coordinate set
- std::vector<aiVector3D> vTextureCoords1;
-
- //! Optional second UV coordinate set
- std::vector<aiVector3D> vTextureCoords2;
-
- //! Specifies whether there are two texture
- //! coordinate sets required
- bool bNeed2UV;
-};
-
-// -------------------------------------------------------------------------------------
-//! Holds data from an MDL7 file that is shared by all mesh groups
-struct IntSharedData_MDL7
-{
- //! Default constructor
- IntSharedData_MDL7()
- {
- abNeedMaterials.reserve(10);
- }
-
- //! Destruction: properly delete all allocated resources
- ~IntSharedData_MDL7()
- {
- // kill all bones
- if (this->apcOutBones)
- {
- for (unsigned int m = 0; m < iNum;++m)
- delete this->apcOutBones[m];
- delete[] this->apcOutBones;
- }
- }
-
- //! Specifies which materials are used
- std::vector<bool> abNeedMaterials;
-
- //! List of all materials
- std::vector<MaterialHelper*> pcMats;
-
- //! List of all bones
- IntBone_MDL7** apcOutBones;
-
- //! number of bones
- unsigned int iNum;
-};
-
-// -------------------------------------------------------------------------------------
-//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
-struct IntSplittedGroupData_MDL7
-{
- //! Construction from a given shared data set
- IntSplittedGroupData_MDL7(IntSharedData_MDL7& _shared,
- std::vector<aiMesh*>& _avOutList)
-
- : shared(_shared), avOutList(_avOutList)
- {
- }
-
- //! Destruction: properly delete all allocated resources
- ~IntSplittedGroupData_MDL7()
- {
- // kill all face lists
- if (this->aiSplit)
- {
- for (unsigned int m = 0; m < shared.pcMats.size();++m)
- delete this->aiSplit[m];
- delete[] this->aiSplit;
- }
- }
-
- //! Contains a list of all faces per material
- std::vector<unsigned int>** aiSplit;
-
- //! Shared data for all groups of the model
- IntSharedData_MDL7& shared;
-
- //! List of meshes
- std::vector<aiMesh*>& avOutList;
-};
-
-
-}
-} // end namespaces
-
-#endif // !! AI_MDLFILEHELPER_H_INC
diff --git a/3rdparty/assimp/code/MDLLoader.cpp b/3rdparty/assimp/code/MDLLoader.cpp
deleted file mode 100644
index 5ee9d850..00000000
--- a/3rdparty/assimp/code/MDLLoader.cpp
+++ /dev/null
@@ -1,1929 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MDLLoader.cpp
- * @brief Implementation of the main parts of the MDL importer class
- * *TODO* Cleanup and further testing of some parts necessary
- */
-
-// internal headers
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-
-#include "MDLLoader.h"
-#include "MDLDefaultColorMap.h"
-#include "MD2FileData.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Ugly stuff ... nevermind
-#define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
- (*((const _type*)(((const char*)_data) + _index * _limit)))
-
-#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
- ((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
-
-#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
- _AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MDLImporter::MDLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MDLImporter::~MDLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- // if check for extension is not enough, check for the magic tokens
- if (extension == "mdl" || !extension.length() || checkSig) {
- uint32_t tokens[8];
- tokens[0] = AI_MDL_MAGIC_NUMBER_LE_HL2a;
- tokens[1] = AI_MDL_MAGIC_NUMBER_LE_HL2b;
- tokens[2] = AI_MDL_MAGIC_NUMBER_LE_GS7;
- tokens[3] = AI_MDL_MAGIC_NUMBER_LE_GS5b;
- tokens[4] = AI_MDL_MAGIC_NUMBER_LE_GS5a;
- tokens[5] = AI_MDL_MAGIC_NUMBER_LE_GS4;
- tokens[6] = AI_MDL_MAGIC_NUMBER_LE_GS3;
- tokens[7] = AI_MDL_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,8,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MDLImporter::SetupProperties(const Importer* pImp)
-{
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME,0xffffffff);
-
- // The
- // AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- if (0xffffffff == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file
- configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported extensions
-void MDLImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert( "mdl" );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MDLImporter::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pScene = _pScene;
- pIOHandler = _pIOHandler;
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open MDL file " + pFile + ".");
- }
-
- // This should work for all other types of MDL files, too ...
- // the quake header is one of the smallest, afaik
- iFileSize = (unsigned int)file->FileSize();
- if ( iFileSize < sizeof(MDL::Header)) {
- throw DeadlyImportError( "MDL File is too small.");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<unsigned char> buffer(iFileSize+1);
- mBuffer = &buffer[0];
- file->Read( (void*)mBuffer, 1, iFileSize);
-
- // Append a binary zero to the end of the buffer.
- // this is just for safety that string parsing routines
- // find the end of the buffer ...
- mBuffer[iFileSize] = '\0';
- const uint32_t iMagicWord = *((uint32_t*)mBuffer);
-
- // Determine the file subtype and call the appropriate member function
-
- // Original Quake1 format
- if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
- iGSFileVersion = 0;
- InternReadFile_Quake1();
- }
- // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
- else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
- iGSFileVersion = 2;
- InternReadFile_Quake1();
- }
- // GameStudio A4 MDL3 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
- iGSFileVersion = 3;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A5+ MDL4 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
- iGSFileVersion = 4;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A5+ MDL5 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
- iGSFileVersion = 5;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A7 MDL7 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
- iGSFileVersion = 7;
- InternReadFile_3DGS_MDL7();
- }
- // IDST/IDSQ Format (CS:S/HL, etc ...)
- else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
- AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
- {
- DefaultLogger::get()->debug("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
- iGSFileVersion = 0;
- InternReadFile_HL2();
- }
- else {
- // print the magic word to the log file
- throw DeadlyImportError( "Unknown MDL subformat " + pFile +
- ". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
- }
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- // delete the file buffer and cleanup
- AI_DEBUG_INVALIDATE_PTR(mBuffer);
- AI_DEBUG_INVALIDATE_PTR(pIOHandler);
- AI_DEBUG_INVALIDATE_PTR(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether we're still inside the valid file range
-void MDLImporter::SizeCheck(const void* szPos)
-{
- if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
- {
- throw DeadlyImportError("Invalid MDL file. The file is too small "
- "or contains invalid data.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Just for debgging purposes
-void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
-{
- ai_assert(NULL != szFile);
- if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize)
- {
- // remove a directory if there is one
- const char* szFilePtr = ::strrchr(szFile,'\\');
- if (!szFilePtr) {
- if (!(szFilePtr = ::strrchr(szFile,'/')))
- szFilePtr = szFile;
- }
- if (szFilePtr)++szFilePtr;
-
- char szBuffer[1024];
- ::sprintf(szBuffer,"Invalid MDL file. The file is too small "
- "or contains invalid data (File: %s Line: %i)",szFilePtr,iLine);
-
- throw DeadlyImportError(szBuffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate a quake file header
-void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
-{
- // some values may not be NULL
- if (!pcHeader->num_frames)
- throw DeadlyImportError( "[Quake 1 MDL] There are no frames in the file");
-
- if (!pcHeader->num_verts)
- throw DeadlyImportError( "[Quake 1 MDL] There are no vertices in the file");
-
- if (!pcHeader->num_tris)
- throw DeadlyImportError( "[Quake 1 MDL] There are no triangles in the file");
-
- // check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only
- if (!this->iGSFileVersion)
- {
- if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
-
- if (pcHeader->num_tris > AI_MDL_MAX_TRIANGLES)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_TRIANGLES triangles");
-
- if (pcHeader->num_frames > AI_MDL_MAX_FRAMES)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_FRAMES frames");
-
- // (this does not apply for 3DGS MDLs)
- if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION)
- DefaultLogger::get()->warn("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is "
- "the expected file format version");
- if (pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
- DefaultLogger::get()->warn("Skin width or height are 0");
- }
-}
-
-#ifdef AI_BUILD_BIG_ENDIAN
-// ------------------------------------------------------------------------------------------------
-void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
-{
- AI_SWAP4( pcHeader->ident);
- AI_SWAP4( pcHeader->version);
- AI_SWAP4( pcHeader->boundingradius);
- AI_SWAP4( pcHeader->flags);
- AI_SWAP4( pcHeader->num_frames);
- AI_SWAP4( pcHeader->num_skins);
- AI_SWAP4( pcHeader->num_tris);
- AI_SWAP4( pcHeader->num_verts);
- for (unsigned int i = 0; i < 3;++i)
- {
- AI_SWAP4( pcHeader->scale[i]);
- AI_SWAP4( pcHeader->translate[i]);
- }
- AI_SWAP4( pcHeader->size);
- AI_SWAP4( pcHeader->skinheight);
- AI_SWAP4( pcHeader->skinwidth);
- AI_SWAP4( pcHeader->synctype);
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Read a Quake 1 file
-void MDLImporter::InternReadFile_Quake1( )
-{
- ai_assert(NULL != pScene);
- BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
-
-#ifdef AI_BUILD_BIG_ENDIAN
- FlipQuakeHeader(pcHeader);
-#endif
-
- ValidateHeader_Quake1(pcHeader);
-
- // current cursor position in the file
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
-
- // need to read all textures
- for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)
- {
- union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;};
- pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
-
- AI_SWAP4( pcSkin->group );
-
- // Quake 1 groupskins
- if (1 == pcSkin->group)
- {
- AI_SWAP4( pcGroupSkin->nb );
-
- // need to skip multiple images
- const unsigned int iNumImages = (unsigned int)pcGroupSkin->nb;
- szCurrent += sizeof(uint32_t) * 2;
-
- if (0 != iNumImages)
- {
- if (!i) {
- // however, create only one output image (the first)
- this->CreateTextureARGB8_3DGS_MDL3(szCurrent + iNumImages * sizeof(float));
- }
- // go to the end of the skin section / the beginning of the next skin
- szCurrent += pcHeader->skinheight * pcHeader->skinwidth +
- sizeof(float) * iNumImages;
- }
- }
- // 3DGS has a few files that are using other 3DGS like texture formats here
- else
- {
- szCurrent += sizeof(uint32_t);
- unsigned int iSkip = i ? 0xffffffff : 0;
- this->CreateTexture_3DGS_MDL4(szCurrent,pcSkin->group,&iSkip);
- szCurrent += iSkip;
- }
- }
- // get a pointer to the texture coordinates
- BE_NCONST MDL::TexCoord* pcTexCoords = (BE_NCONST MDL::TexCoord*)szCurrent;
- szCurrent += sizeof(MDL::TexCoord) * pcHeader->num_verts;
-
- // get a pointer to the triangles
- BE_NCONST MDL::Triangle* pcTriangles = (BE_NCONST MDL::Triangle*)szCurrent;
- szCurrent += sizeof(MDL::Triangle) * pcHeader->num_tris;
- VALIDATE_FILE_SIZE(szCurrent);
-
- // now get a pointer to the first frame in the file
- BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
- BE_NCONST MDL::SimpleFrame* pcFirstFrame;
-
- if (0 == pcFrames->type)
- {
- // get address of single frame
- pcFirstFrame = &pcFrames->frame;
- }
- else
- {
- // get the first frame in the group
- BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
- pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
- }
- BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
- VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
-
-#ifdef AI_BUILD_BIG_ENDIAN
- for (int i = 0; i<pcHeader->num_verts;++i)
- {
- AI_SWAP4( pcTexCoords[i].onseam );
- AI_SWAP4( pcTexCoords[i].s );
- AI_SWAP4( pcTexCoords[i].t );
- }
-
- for (int i = 0; i<pcHeader->num_tris;++i)
- {
- AI_SWAP4( pcTriangles[i].facesfront);
- AI_SWAP4( pcTriangles[i].vertex[0]);
- AI_SWAP4( pcTriangles[i].vertex[1]);
- AI_SWAP4( pcTriangles[i].vertex[2]);
- }
-#endif
-
- // setup materials
- SetupMaterialProperties_3DGS_MDL5_Quake1();
-
- // allocate enough storage to hold all vertices and triangles
- aiMesh* pcMesh = new aiMesh();
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mNumVertices = pcHeader->num_tris * 3;
- pcMesh->mNumFaces = pcHeader->num_tris;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // there won't be more than one mesh inside the file
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = pcMesh;
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)
- {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent)
- {
- pcMesh->mFaces[i].mIndices[c] = iCurrent;
-
- // read vertices
- unsigned int iIndex = pcTriangles->vertex[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts)
- {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in Q1-MDL vertex list.");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- //vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- //pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- float s = (float)pcTexCoords[iIndex].s;
- float t = (float)pcTexCoords[iIndex].t;
-
- // translate texture coordinates
- if (0 == pcTriangles->facesfront && 0 != pcTexCoords[iIndex].onseam) {
- s += pcHeader->skinwidth * 0.5f;
- }
-
- // Scale s and t to range from 0.0 to 1.0
- pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth;
- pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / pcHeader->skinheight;
-
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup material properties for Quake and older GameStudio files
-void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
-{
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
-
- // allocate ONE material
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = new MaterialHelper();
- pScene->mNumMaterials = 1;
-
- // setup the material's properties
- const int iMode = (int)aiShadingMode_Gouraud;
- MaterialHelper* const pcHelper = (MaterialHelper*)pScene->mMaterials[0];
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor4D clr;
- if (0 != pcHeader->num_skins && pScene->mNumTextures) {
- // can we replace the texture with a single color?
- clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
- if (is_not_qnan(clr.r)) {
- delete pScene->mTextures[0];
- delete[] pScene->mTextures;
-
- pScene->mTextures = NULL;
- pScene->mNumTextures = 0;
- }
- else {
- clr.b = clr.a = clr.g = clr.r = 1.0f;
- aiString szString;
- ::memcpy(szString.data,AI_MAKE_EMBEDDED_TEXNAME(0),3);
- szString.length = 2;
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.r *= 0.05f;clr.g *= 0.05f;
- clr.b *= 0.05f;clr.a = 1.0f;
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a MDL 3,4,5 file
-void MDLImporter::InternReadFile_3DGS_MDL345( )
-{
- ai_assert(NULL != pScene);
-
- // the header of MDL 3/4/5 is nearly identical to the original Quake1 header
- BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
-#ifdef AI_BUILD_BIG_ENDIAN
- FlipQuakeHeader(pcHeader);
-#endif
- ValidateHeader_Quake1(pcHeader);
-
- // current cursor position in the file
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
-
- // need to read all textures
- for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) {
- BE_NCONST MDL::Skin* pcSkin;
- pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
- AI_SWAP4( pcSkin->group);
- // create one output image
- unsigned int iSkip = i ? 0xffffffff : 0;
- if (5 <= iGSFileVersion)
- {
- // MDL5 format could contain MIPmaps
- CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
- pcSkin->group,&iSkip);
- }
- else {
- CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
- pcSkin->group,&iSkip);
- }
- // need to skip one image
- szCurrent += iSkip + sizeof(uint32_t);
-
- }
- // get a pointer to the texture coordinates
- BE_NCONST MDL::TexCoord_MDL3* pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3*)szCurrent;
- szCurrent += sizeof(MDL::TexCoord_MDL3) * pcHeader->synctype;
-
- // NOTE: for MDLn formats "synctype" corresponds to the number of UV coords
-
- // get a pointer to the triangles
- BE_NCONST MDL::Triangle_MDL3* pcTriangles = (BE_NCONST MDL::Triangle_MDL3*)szCurrent;
- szCurrent += sizeof(MDL::Triangle_MDL3) * pcHeader->num_tris;
-
-#ifdef AI_BUILD_BIG_ENDIAN
-
- for (int i = 0; i<pcHeader->synctype;++i) {
- AI_SWAP2( pcTexCoords[i].u );
- AI_SWAP2( pcTexCoords[i].v );
- }
-
- for (int i = 0; i<pcHeader->num_tris;++i) {
- AI_SWAP2( pcTriangles[i].index_xyz[0]);
- AI_SWAP2( pcTriangles[i].index_xyz[1]);
- AI_SWAP2( pcTriangles[i].index_xyz[2]);
- AI_SWAP2( pcTriangles[i].index_uv[0]);
- AI_SWAP2( pcTriangles[i].index_uv[1]);
- AI_SWAP2( pcTriangles[i].index_uv[2]);
- }
-
-#endif
-
- VALIDATE_FILE_SIZE(szCurrent);
-
- // setup materials
- SetupMaterialProperties_3DGS_MDL5_Quake1();
-
- // allocate enough storage to hold all vertices and triangles
- aiMesh* pcMesh = new aiMesh();
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pcMesh->mNumVertices = pcHeader->num_tris * 3;
- pcMesh->mNumFaces = pcHeader->num_tris;
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- // there won't be more than one mesh inside the file
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = pcMesh;
-
- // allocate output storage
- pcMesh->mNumVertices = (unsigned int)pcHeader->num_tris*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- if (pcHeader->synctype) {
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
- }
-
- // now get a pointer to the first frame in the file
- BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
- AI_SWAP4(pcFrames->type);
-
- // byte packed vertices
- // FIXME: these two snippets below are almost identical ... join them?
- /////////////////////////////////////////////////////////////////////////////////////
- if (0 == pcFrames->type || 3 >= this->iGSFileVersion) {
-
- const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
- const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
-
- VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- // read vertices
- unsigned int iIndex = pcTriangles->index_xyz[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts) {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- // vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- // pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- if (pcHeader->synctype) {
- ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
- pcTexCoords,pcTriangles->index_uv[c]);
- }
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
-
- }
- // short packed vertices
- /////////////////////////////////////////////////////////////////////////////////////
- else {
- // now get a pointer to the first frame in the file
- const MDL::SimpleFrame_MDLn_SP* pcFirstFrame = (const MDL::SimpleFrame_MDLn_SP*) (szCurrent + sizeof(uint32_t));
-
- // get a pointer to the vertices
- const MDL::Vertex_MDL4* pcVertices = (const MDL::Vertex_MDL4*) ((pcFirstFrame->name) +
- sizeof(pcFirstFrame->name));
-
- VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- // read vertices
- unsigned int iIndex = pcTriangles->index_xyz[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts) {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- // vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- // pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- if (pcHeader->synctype) {
- ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
- pcTexCoords,pcTriangles->index_uv[c]);
- }
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
- }
-
- // For MDL5 we will need to build valid texture coordinates
- // basing upon the file loaded (only support one file as skin)
- if (0x5 == iGSFileVersion)
- CalculateUVCoordinates_MDL5();
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a single UV coordinate for Quake and older GameStudio files
-void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
- aiVector3D& vOut,
- const MDL::TexCoord_MDL3* pcSrc,
- unsigned int iIndex)
-{
- ai_assert(NULL != pcSrc);
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
-
- // validate UV indices
- if (iIndex >= (unsigned int) pcHeader->synctype) {
- iIndex = pcHeader->synctype-1;
- DefaultLogger::get()->warn("Index overflow in MDLn UV coord list");
- }
-
- float s = (float)pcSrc[iIndex].u;
- float t = (float)pcSrc[iIndex].v;
-
- // Scale s and t to range from 0.0 to 1.0
- if (0x5 != iGSFileVersion) {
- s = (s + 0.5f) / pcHeader->skinwidth;
- t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
- }
-
- vOut.x = s;
- vOut.y = t;
- vOut.z = 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compute UV coordinates for a MDL5 file
-void MDLImporter::CalculateUVCoordinates_MDL5()
-{
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
- if (pcHeader->num_skins && this->pScene->mNumTextures) {
- const aiTexture* pcTex = this->pScene->mTextures[0];
-
- // if the file is loaded in DDS format: get the size of the
- // texture from the header of the DDS file
- // skip three DWORDs and read first height, then the width
- unsigned int iWidth, iHeight;
- if (!pcTex->mHeight) {
- const uint32_t* piPtr = (uint32_t*)pcTex->pcData;
-
- piPtr += 3;
- iHeight = (unsigned int)*piPtr++;
- iWidth = (unsigned int)*piPtr;
- if (!iHeight || !iWidth)
- {
- DefaultLogger::get()->warn("Either the width or the height of the "
- "embedded DDS texture is zero. Unable to compute final texture "
- "coordinates. The texture coordinates remain in their original "
- "0-x/0-y (x,y = texture size) range.");
- iWidth = 1;
- iHeight = 1;
- }
- }
- else {
- iWidth = pcTex->mWidth;
- iHeight = pcTex->mHeight;
- }
-
- if (1 != iWidth || 1 != iHeight) {
- const float fWidth = (float)iWidth;
- const float fHeight = (float)iHeight;
- aiMesh* pcMesh = this->pScene->mMeshes[0];
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- {
- pcMesh->mTextureCoords[0][i].x /= fWidth;
- pcMesh->mTextureCoords[0][i].y /= fHeight;
- pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of a MDL7 file
-void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
-{
- ai_assert(NULL != pcHeader);
-
- // There are some fixed sizes ...
- if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
- throw DeadlyImportError(
- "[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
- }
- if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size) {
- throw DeadlyImportError(
- "[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
- }
- if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size) {
- throw DeadlyImportError(
- "sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
- }
-
- // if there are no groups ... how should we load such a file?
- if (!pcHeader->groups_num) {
- throw DeadlyImportError( "[3DGS MDL7] No frames found");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// resolve bone animation matrices
-void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- const MDL::Bone_MDL7* pcBones = (const MDL::Bone_MDL7*)(pcHeader+1);
- ai_assert(NULL != apcOutBones);
-
- // first find the bone that has NO parent, calculate the
- // animation matrix for it, then go on and search for the next parent
- // index (0) and so on until we can't find a new node.
- uint16_t iParent = 0xffff;
- uint32_t iIterations = 0;
- while (iIterations++ < pcHeader->bones_num) {
- for (uint32_t iBone = 0; iBone < pcHeader->bones_num;++iBone) {
- BE_NCONST MDL::Bone_MDL7* pcBone = _AI_MDL7_ACCESS_PTR(pcBones,iBone,
- pcHeader->bone_stc_size,MDL::Bone_MDL7);
-
- AI_SWAP2(pcBone->parent_index);
- AI_SWAP4(pcBone->x);
- AI_SWAP4(pcBone->y);
- AI_SWAP4(pcBone->z);
-
- if (iParent == pcBone->parent_index) {
- // MDL7 readme
- ////////////////////////////////////////////////////////////////
- /*
- The animation matrix is then calculated the following way:
-
- vector3 bPos = <absolute bone position>
- matrix44 laM; // local animation matrix
- sphrvector key_rotate = <bone rotation>
-
- matrix44 m1,m2;
- create_trans_matrix(m1, -bPos.x, -bPos.y, -bPos.z);
- create_trans_matrix(m2, -bPos.x, -bPos.y, -bPos.z);
-
- create_rotation_matrix(laM,key_rotate);
-
- laM = sm1 * laM;
- laM = laM * sm2;
- */
- /////////////////////////////////////////////////////////////////
-
- MDL::IntBone_MDL7* const pcOutBone = apcOutBones[iBone];
-
- // store the parent index of the bone
- pcOutBone->iParent = pcBone->parent_index;
- if (0xffff != iParent) {
- const MDL::IntBone_MDL7* pcParentBone = apcOutBones[iParent];
- pcOutBone->mOffsetMatrix.a4 = -pcParentBone->vPosition.x;
- pcOutBone->mOffsetMatrix.b4 = -pcParentBone->vPosition.y;
- pcOutBone->mOffsetMatrix.c4 = -pcParentBone->vPosition.z;
- }
- pcOutBone->vPosition.x = pcBone->x;
- pcOutBone->vPosition.y = pcBone->y;
- pcOutBone->vPosition.z = pcBone->z;
- pcOutBone->mOffsetMatrix.a4 -= pcBone->x;
- pcOutBone->mOffsetMatrix.b4 -= pcBone->y;
- pcOutBone->mOffsetMatrix.c4 -= pcBone->z;
-
- if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size) {
- // no real name for our poor bone is specified :-(
- pcOutBone->mName.length = ::sprintf(pcOutBone->mName.data,
- "UnnamedBone_%i",iBone);
- }
- else {
- // Make sure we won't run over the buffer's end if there is no
- // terminal 0 character (however the documentation says there
- // should be one)
- uint32_t iMaxLen = pcHeader->bone_stc_size-16;
- for (uint32_t qq = 0; qq < iMaxLen;++qq) {
- if (!pcBone->name[qq]) {
- iMaxLen = qq;
- break;
- }
- }
-
- // store the name of the bone
- pcOutBone->mName.length = (size_t)iMaxLen;
- ::memcpy(pcOutBone->mName.data,pcBone->name,pcOutBone->mName.length);
- pcOutBone->mName.data[pcOutBone->mName.length] = '\0';
- }
- }
- }
- ++iParent;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read bones from a MDL7 file
-MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- if (pcHeader->bones_num) {
- // validate the size of the bone data structure in the file
- if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size &&
- AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
- AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size)
- {
- DefaultLogger::get()->warn("Unknown size of bone data structure");
- return NULL;
- }
-
- MDL::IntBone_MDL7** apcBonesOut = new MDL::IntBone_MDL7*[pcHeader->bones_num];
- for (uint32_t crank = 0; crank < pcHeader->bones_num;++crank)
- apcBonesOut[crank] = new MDL::IntBone_MDL7();
-
- // and calculate absolute bone offset matrices ...
- CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
- return apcBonesOut;
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// read faces from a MDL7 file
-void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData)
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- BE_NCONST MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
-
- // iterate through all triangles and build valid display lists
- unsigned int iOutIndex = 0;
- for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
- AI_SWAP2(pcGroupTris->v_index[0]);
- AI_SWAP2(pcGroupTris->v_index[1]);
- AI_SWAP2(pcGroupTris->v_index[2]);
-
- // iterate through all indices of the current triangle
- for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
-
- // validate the vertex index
- unsigned int iIndex = pcGroupTris->v_index[c];
- if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
- // (we might need to read this section a second time - to process frame vertices correctly)
- const_cast<MDL::Triangle_MDL7*>(pcGroupTris)->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
- }
-
- // write the output face index
- groupData.pcFaces[iTriangle].mIndices[2-c] = iOutIndex;
-
- aiVector3D& vPosition = groupData.vPositions[ iOutIndex ];
- vPosition.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex, pcHeader->mainvertex_stc_size) .x;
- vPosition.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .y;
- vPosition.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .z;
-
- // if we have bones, save the index
- if (!groupData.aiBones.empty()) {
- groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,
- iIndex,pcHeader->mainvertex_stc_size).vertindex;
- }
-
- // now read the normal vector
- if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the full normal vector
- aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
- vNormal.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[0];
- AI_SWAP4(vNormal.x);
- vNormal.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[1];
- AI_SWAP4(vNormal.y);
- vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[2];
- AI_SWAP4(vNormal.z);
- }
- else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the normal vector from Quake2's smart table
- aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
- MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,
- pcHeader->mainvertex_stc_size) .norm162index,vNormal);
- }
- // validate and process the first uv coordinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
-
- if (groupInfo.pcGroup->num_stpts) {
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[0]);
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[1]);
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[2]);
-
- iIndex = pcGroupTris->skinsets[0].st_index[c];
- if (iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
- iIndex = groupInfo.pcGroup->num_stpts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#1)");
- }
-
- float u = groupInfo.pcGroupUVs[iIndex].u;
- float v = 1.0f-groupInfo.pcGroupUVs[iIndex].v; // DX to OGL
-
- groupData.vTextureCoords1[iOutIndex].x = u;
- groupData.vTextureCoords1[iOutIndex].y = v;
- }
- // assign the material index, but only if it is existing
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX){
- AI_SWAP4(pcGroupTris->skinsets[0].material);
- groupData.pcFaces[iTriangle].iMatIndex[0] = pcGroupTris->skinsets[0].material;
- }
- }
- // validate and process the second uv coordinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
-
- if (groupInfo.pcGroup->num_stpts) {
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[0]);
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[1]);
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[2]);
- AI_SWAP4(pcGroupTris->skinsets[1].material);
-
- iIndex = pcGroupTris->skinsets[1].st_index[c];
- if (iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
- iIndex = groupInfo.pcGroup->num_stpts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#2)");
- }
-
- float u = groupInfo.pcGroupUVs[ iIndex ].u;
- float v = 1.0f-groupInfo.pcGroupUVs[ iIndex ].v;
-
- groupData.vTextureCoords2[ iOutIndex ].x = u;
- groupData.vTextureCoords2[ iOutIndex ].y = v; // DX to OGL
-
- // check whether we do really need the second texture
- // coordinate set ... wastes memory and loading time
- if (0 != iIndex && (u != groupData.vTextureCoords1[ iOutIndex ].x ||
- v != groupData.vTextureCoords1[ iOutIndex ].y ) )
- groupData.bNeed2UV = true;
-
- // if the material differs, we need a second skin, too
- if (pcGroupTris->skinsets[ 1 ].material != pcGroupTris->skinsets[ 0 ].material)
- groupData.bNeed2UV = true;
- }
- // assign the material index
- groupData.pcFaces[ iTriangle ].iMatIndex[ 1 ] = pcGroupTris->skinsets[ 1 ].material;
- }
- }
- // get the next triangle in the list
- pcGroupTris = (BE_NCONST MDL::Triangle_MDL7*)((const char*)pcGroupTris + pcHeader->triangle_stc_size);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// handle frames in a MDL7 file
-bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSharedData_MDL7& shared,
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut)
-{
- ai_assert(NULL != szCurrent && NULL != szCurrentOut);
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
-
- // if we have no bones we can simply skip all frames,
- // otherwise we'll need to process them.
- // FIX: If we need another frame than the first we must apply frame vertex replacements ...
- for (unsigned int iFrame = 0; iFrame < (unsigned int)groupInfo.pcGroup->numframes;++iFrame) {
- MDL::IntFrameInfo_MDL7 frame ((BE_NCONST MDL::Frame_MDL7*)szCurrent,iFrame);
-
- AI_SWAP4(frame.pcFrame->vertices_count);
- AI_SWAP4(frame.pcFrame->transmatrix_count);
-
- const unsigned int iAdd = pcHeader->frame_stc_size +
- frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
- frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
-
- if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
- DefaultLogger::get()->warn("Index overflow in frame area. "
- "Ignoring all frames and all further mesh groups, too.");
-
- // don't parse more groups if we can't even read one
- // FIXME: sometimes this seems to occur even for valid files ...
- *szCurrentOut = szCurrent;
- return false;
- }
- // our output frame?
- if (configFrameID == iFrame) {
- BE_NCONST MDL::Vertex_MDL7* pcFrameVertices = (BE_NCONST MDL::Vertex_MDL7*)(szCurrent+pcHeader->frame_stc_size);
-
- for (unsigned int qq = 0; qq < frame.pcFrame->vertices_count;++qq) {
- // I assume this are simple replacements for normal vertices, the bone index serving
- // as the index of the vertex to be replaced.
- uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex;
- AI_SWAP2(iIndex);
- if (iIndex >= groupInfo.pcGroup->numverts) {
- DefaultLogger::get()->warn("Invalid vertex index in frame vertex section");
- continue;
- }
-
- aiVector3D vPosition,vNormal;
-
- vPosition.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .x;
- AI_SWAP4(vPosition.x);
- vPosition.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .y;
- AI_SWAP4(vPosition.y);
- vPosition.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .z;
- AI_SWAP4(vPosition.z);
-
- // now read the normal vector
- if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the full normal vector
- vNormal.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[0];
- AI_SWAP4(vNormal.x);
- vNormal.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[1];
- AI_SWAP4(vNormal.y);
- vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[2];
- AI_SWAP4(vNormal.z);
- }
- else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the normal vector from Quake2's smart table
- MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,
- pcHeader->framevertex_stc_size) .norm162index,vNormal);
- }
-
- // FIXME: O(n^2) at the moment ...
- BE_NCONST MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
- unsigned int iOutIndex = 0;
- for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
- // iterate through all indices of the current triangle
- for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
- // replace the vertex with the new data
- const unsigned int iCurIndex = pcGroupTris->v_index[c];
- if (iCurIndex == iIndex) {
- groupData.vPositions[iOutIndex] = vPosition;
- groupData.vNormals[iOutIndex] = vNormal;
- }
- }
- // get the next triangle in the list
- pcGroupTris = (BE_NCONST MDL::Triangle_MDL7*)((const char*)
- pcGroupTris + pcHeader->triangle_stc_size);
- }
- }
- }
- // parse bone trafo matrix keys (only if there are bones ...)
- if (shared.apcOutBones) {
- ParseBoneTrafoKeys_3DGS_MDL7(groupInfo,frame,shared);
- }
- szCurrent += iAdd;
- }
- *szCurrentOut = szCurrent;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Sort faces by material, handle multiple UVs correctly
-void MDLImporter::SortByMaterials_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplittedGroupData_MDL7& splittedGroupData)
-{
- const unsigned int iNumMaterials = (unsigned int)splittedGroupData.shared.pcMats.size();
- if (!groupData.bNeed2UV) {
- // if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
- groupData.vTextureCoords2.clear();
-
- // allocate the array
- splittedGroupData.aiSplit = new std::vector<unsigned int>*[iNumMaterials];
-
- for (unsigned int m = 0; m < iNumMaterials;++m)
- splittedGroupData.aiSplit[m] = new std::vector<unsigned int>();
-
- // iterate through all faces and sort by material
- for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
- // check range
- if (groupData.pcFaces[iFace].iMatIndex[0] >= iNumMaterials) {
- // use the last material instead
- splittedGroupData.aiSplit[iNumMaterials-1]->push_back(iFace);
-
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- if (0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]");
- }
- else splittedGroupData.aiSplit[groupData.pcFaces[iFace].
- iMatIndex[0]]->push_back(iFace);
- }
- }
- else
- {
- // we need to build combined materials for each combination of
- std::vector<MDL::IntMaterial_MDL7> avMats;
- avMats.reserve(iNumMaterials*2);
-
- // fixme: why on the heap?
- std::vector<std::vector<unsigned int>* > aiTempSplit(iNumMaterials*2);
- for (unsigned int m = 0; m < iNumMaterials;++m)
- aiTempSplit[m] = new std::vector<unsigned int>();
-
- // iterate through all faces and sort by material
- for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
- // check range
- unsigned int iMatIndex = groupData.pcFaces[iFace].iMatIndex[0];
- if (iMatIndex >= iNumMaterials) {
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- if (0xffffffff != iMatIndex)
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]");
- iMatIndex = iNumMaterials-1;
- }
- unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
-
- unsigned int iNum = iMatIndex;
- if (0xffffffff != iMatIndex2 && iMatIndex != iMatIndex2) {
- if (iMatIndex2 >= iNumMaterials) {
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]");
- iMatIndex2 = iNumMaterials-1;
- }
-
- // do a slow seach in the list ...
- iNum = 0;
- bool bFound = false;
- for (std::vector<MDL::IntMaterial_MDL7>::iterator i = avMats.begin();i != avMats.end();++i,++iNum){
- if ((*i).iOldMatIndices[0] == iMatIndex && (*i).iOldMatIndices[1] == iMatIndex2) {
- // reuse this material
- bFound = true;
- break;
- }
- }
- if (!bFound) {
- // build a new material ...
- MDL::IntMaterial_MDL7 sHelper;
- sHelper.pcMat = new MaterialHelper();
- sHelper.iOldMatIndices[0] = iMatIndex;
- sHelper.iOldMatIndices[1] = iMatIndex2;
- JoinSkins_3DGS_MDL7(splittedGroupData.shared.pcMats[iMatIndex],
- splittedGroupData.shared.pcMats[iMatIndex2],sHelper.pcMat);
-
- // and add it to the list
- avMats.push_back(sHelper);
- iNum = (unsigned int)avMats.size()-1;
- }
- // adjust the size of the file array
- if (iNum == aiTempSplit.size()) {
- aiTempSplit.push_back(new std::vector<unsigned int>());
- }
- }
- aiTempSplit[iNum]->push_back(iFace);
- }
-
- // now add the newly created materials to the old list
- if (0 == groupInfo.iIndex) {
- splittedGroupData.shared.pcMats.resize(avMats.size());
- for (unsigned int o = 0; o < avMats.size();++o)
- splittedGroupData.shared.pcMats[o] = avMats[o].pcMat;
- }
- else {
- // This might result in redundant materials ...
- splittedGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
- for (unsigned int o = iNumMaterials; o < avMats.size();++o)
- splittedGroupData.shared.pcMats[o] = avMats[o].pcMat;
- }
-
- // and build the final face-to-material array
- splittedGroupData.aiSplit = new std::vector<unsigned int>*[aiTempSplit.size()];
- for (unsigned int m = 0; m < iNumMaterials;++m)
- splittedGroupData.aiSplit[m] = aiTempSplit[m];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a MDL7 file
-void MDLImporter::InternReadFile_3DGS_MDL7( )
-{
- ai_assert(NULL != pScene);
-
- MDL::IntSharedData_MDL7 sharedData;
-
- // current cursor position in the file
- BE_NCONST MDL::Header_MDL7 *pcHeader = (BE_NCONST MDL::Header_MDL7*)this->mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
-
- AI_SWAP4(pcHeader->version);
- AI_SWAP4(pcHeader->bones_num);
- AI_SWAP4(pcHeader->groups_num);
- AI_SWAP4(pcHeader->data_size);
- AI_SWAP4(pcHeader->entlump_size);
- AI_SWAP4(pcHeader->medlump_size);
- AI_SWAP2(pcHeader->bone_stc_size);
- AI_SWAP2(pcHeader->skin_stc_size);
- AI_SWAP2(pcHeader->colorvalue_stc_size);
- AI_SWAP2(pcHeader->material_stc_size);
- AI_SWAP2(pcHeader->skinpoint_stc_size);
- AI_SWAP2(pcHeader->triangle_stc_size);
- AI_SWAP2(pcHeader->mainvertex_stc_size);
- AI_SWAP2(pcHeader->framevertex_stc_size);
- AI_SWAP2(pcHeader->bonetrans_stc_size);
- AI_SWAP2(pcHeader->frame_stc_size);
-
- // validate the header of the file. There are some structure
- // sizes that are expected by the loader to be constant
- this->ValidateHeader_3DGS_MDL7(pcHeader);
-
- // load all bones (they are shared by all groups, so
- // we'll need to add them to all groups/meshes later)
- // apcBonesOut is a list of all bones or NULL if they could not been loaded
- szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
- sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
-
- // vector to held all created meshes
- std::vector<aiMesh*>* avOutList;
-
- // 3 meshes per group - that should be OK for most models
- avOutList = new std::vector<aiMesh*>[pcHeader->groups_num];
- for (uint32_t i = 0; i < pcHeader->groups_num;++i)
- avOutList[i].reserve(3);
-
- // buffer to held the names of all groups in the file
- char* aszGroupNameBuffer = new char[AI_MDL7_MAX_GROUPNAMESIZE*pcHeader->groups_num];
-
- // read all groups
- for (unsigned int iGroup = 0; iGroup < (unsigned int)pcHeader->groups_num;++iGroup) {
- MDL::IntGroupInfo_MDL7 groupInfo((BE_NCONST MDL::Group_MDL7*)szCurrent,iGroup);
- szCurrent = (const unsigned char*)(groupInfo.pcGroup+1);
-
- VALIDATE_FILE_SIZE(szCurrent);
-
- AI_SWAP4(groupInfo.pcGroup->groupdata_size);
- AI_SWAP4(groupInfo.pcGroup->numskins);
- AI_SWAP4(groupInfo.pcGroup->num_stpts);
- AI_SWAP4(groupInfo.pcGroup->numtris);
- AI_SWAP4(groupInfo.pcGroup->numverts);
- AI_SWAP4(groupInfo.pcGroup->numframes);
-
- if (1 != groupInfo.pcGroup->typ) {
- // Not a triangle-based mesh
- DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
- }
-
- // store the name of the group
- const unsigned int ofs = iGroup*AI_MDL7_MAX_GROUPNAMESIZE;
- ::memcpy(&aszGroupNameBuffer[ofs],
- groupInfo.pcGroup->name,AI_MDL7_MAX_GROUPNAMESIZE);
-
- // make sure '\0' is at the end
- aszGroupNameBuffer[ofs+AI_MDL7_MAX_GROUPNAMESIZE-1] = '\0';
-
- // read all skins
- sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins);
- sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
- groupInfo.pcGroup->numskins,false);
-
- for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins;++iSkin) {
- ParseSkinLump_3DGS_MDL7(szCurrent,&szCurrent,sharedData.pcMats);
- }
- // if we have absolutely no skin loaded we need to generate a default material
- if (sharedData.pcMats.empty()) {
- const int iMode = (int)aiShadingMode_Gouraud;
- sharedData.pcMats.push_back(new MaterialHelper());
- MaterialHelper* pcHelper = (MaterialHelper*)sharedData.pcMats[0];
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- sharedData.abNeedMaterials.resize(1,false);
- }
-
- // now get a pointer to all texture coords in the group
- groupInfo.pcGroupUVs = (BE_NCONST MDL::TexCoord_MDL7*)szCurrent;
- for (int i = 0; i < groupInfo.pcGroup->num_stpts; ++i){
- AI_SWAP4(groupInfo.pcGroupUVs[i].u);
- AI_SWAP4(groupInfo.pcGroupUVs[i].v);
- }
- szCurrent += pcHeader->skinpoint_stc_size * groupInfo.pcGroup->num_stpts;
-
- // now get a pointer to all triangle in the group
- groupInfo.pcGroupTris = (BE_NCONST MDL::Triangle_MDL7*)szCurrent;
- szCurrent += pcHeader->triangle_stc_size * groupInfo.pcGroup->numtris;
-
- // now get a pointer to all vertices in the group
- groupInfo.pcGroupVerts = (BE_NCONST MDL::Vertex_MDL7*)szCurrent;
- for (int i = 0; i < groupInfo.pcGroup->numverts; ++i){
- AI_SWAP4(groupInfo.pcGroupVerts[i].x);
- AI_SWAP4(groupInfo.pcGroupVerts[i].y);
- AI_SWAP4(groupInfo.pcGroupVerts[i].z);
-
- AI_SWAP2(groupInfo.pcGroupVerts[i].vertindex);
- //We can not swap the normal information now as we don't know which of the two kinds it is
- }
- szCurrent += pcHeader->mainvertex_stc_size * groupInfo.pcGroup->numverts;
- VALIDATE_FILE_SIZE(szCurrent);
-
- MDL::IntSplittedGroupData_MDL7 splittedGroupData(sharedData,avOutList[iGroup]);
- MDL::IntGroupData_MDL7 groupData;
- if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts)
- {
- // build output vectors
- const unsigned int iNumVertices = groupInfo.pcGroup->numtris*3;
- groupData.vPositions.resize(iNumVertices);
- groupData.vNormals.resize(iNumVertices);
-
- if (sharedData.apcOutBones)groupData.aiBones.resize(iNumVertices,0xffffffff);
-
- // it is also possible that there are 0 UV coordinate sets
- if (groupInfo.pcGroup->num_stpts){
- groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
-
- // check whether the triangle data structure is large enough
- // to contain a second UV coodinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
- groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
- groupData.bNeed2UV = true;
- }
- }
- groupData.pcFaces = new MDL::IntFace_MDL7[groupInfo.pcGroup->numtris];
-
- // read all faces into the preallocated arrays
- ReadFaces_3DGS_MDL7(groupInfo, groupData);
-
- // sort by materials
- SortByMaterials_3DGS_MDL7(groupInfo, groupData,
- splittedGroupData);
-
- for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq) {
- if (!splittedGroupData.aiSplit[qq]->empty())
- sharedData.abNeedMaterials[qq] = true;
- }
- }
- else DefaultLogger::get()->warn("[3DGS MDL7] Mesh group consists of 0 "
- "vertices or faces. It will be skipped.");
-
- // process all frames and generate output meshes
- ProcessFrames_3DGS_MDL7(groupInfo,groupData, sharedData,szCurrent,&szCurrent);
- GenerateOutputMeshes_3DGS_MDL7(groupData,splittedGroupData);
- }
-
- // generate a nodegraph and subnodes for each group
- pScene->mRootNode = new aiNode();
-
- // now we need to build a final mesh list
- for (uint32_t i = 0; i < pcHeader->groups_num;++i)
- pScene->mNumMeshes += (unsigned int)avOutList[i].size();
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; {
- unsigned int p = 0,q = 0;
- for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
- for (unsigned int a = 0; a < avOutList[i].size();++a) {
- pScene->mMeshes[p++] = avOutList[i][a];
- }
- if (!avOutList[i].empty())++pScene->mRootNode->mNumChildren;
- }
- // we will later need an extra node to serve as parent for all bones
- if (sharedData.apcOutBones)++pScene->mRootNode->mNumChildren;
- this->pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
- p = 0;
- for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
- if (avOutList[i].empty())continue;
-
- aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
- pcNode->mNumMeshes = (unsigned int)avOutList[i].size();
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- pcNode->mParent = this->pScene->mRootNode;
- for (unsigned int a = 0; a < pcNode->mNumMeshes;++a)
- pcNode->mMeshes[a] = q + a;
- q += (unsigned int)avOutList[i].size();
-
- // setup the name of the node
- char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
- if ('\0' == *szBuffer)
- pcNode->mName.length = ::sprintf(szBuffer,"Group_%i",p);
- else pcNode->mName.length = ::strlen(szBuffer);
- ::strcpy(pcNode->mName.data,szBuffer);
- ++p;
- }
- }
-
- // if there is only one root node with a single child we can optimize it a bit ...
- if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
- aiNode* pcOldRoot = this->pScene->mRootNode;
- pScene->mRootNode = pcOldRoot->mChildren[0];
- pcOldRoot->mChildren[0] = NULL;
- delete pcOldRoot;
- pScene->mRootNode->mParent = NULL;
- }
- else pScene->mRootNode->mName.Set("<mesh_root>");
-
- delete[] avOutList;
- delete[] aszGroupNameBuffer;
- AI_DEBUG_INVALIDATE_PTR(avOutList);
- AI_DEBUG_INVALIDATE_PTR(aszGroupNameBuffer);
-
- // build a final material list.
- CopyMaterials_3DGS_MDL7(sharedData);
- HandleMaterialReferences_3DGS_MDL7();
-
- // generate output bone animations and add all bones to the scenegraph
- if (sharedData.apcOutBones) {
- // this step adds empty dummy bones to the nodegraph
- // insert another dummy node to avoid name conflicts
- aiNode* const pc = pScene->mRootNode->mChildren[pScene->mRootNode->mNumChildren-1] = new aiNode();
-
- pc->mName.Set("<skeleton_root>");
-
- // add bones to the nodegraph
- AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
- sharedData.apcOutBones,pc,0xffff);
-
- // this steps build a valid output animation
- BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
- sharedData.apcOutBones);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy materials
-void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
-{
- pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- pScene->mMaterials[i] = shared.pcMats[i];
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Process material references
-void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
-{
- // search for referrer materials
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- int iIndex = 0;
- if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],AI_MDL7_REFERRER_MATERIAL, &iIndex) ) {
- for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
- aiMesh* const pcMesh = pScene->mMeshes[a];
- if (i == pcMesh->mMaterialIndex) {
- pcMesh->mMaterialIndex = iIndex;
- }
- }
- // collapse the rest of the array
- delete pScene->mMaterials[i];
- for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp) {
-
- pScene->mMaterials[pp] = pScene->mMaterials[pp+1];
- for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
- aiMesh* const pcMesh = pScene->mMeshes[a];
- if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
- }
- }
- --pScene->mNumMaterials;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read bone transformation keys
-void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- IntFrameInfo_MDL7& frame,
- MDL::IntSharedData_MDL7& shared)
-{
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
-
- // only the first group contains bone animation keys
- if (frame.pcFrame->transmatrix_count) {
- if (!groupInfo.iIndex) {
- // skip all frames vertices. We can't support them
- const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*)
- (((const char*)frame.pcFrame) + pcHeader->frame_stc_size +
- frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
-
- // read all transformation matrices
- for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) {
- if (pcBoneTransforms->bone_index >= pcHeader->bones_num) {
- DefaultLogger::get()->warn("Index overflow in frame area. "
- "Unable to parse this bone transformation");
- }
- else {
- AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
- pcBoneTransforms,shared.apcOutBones);
- }
- pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
- (const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
- }
- }
- else {
- DefaultLogger::get()->warn("Ignoring animation keyframes in groups != 0");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Attach bones to the output nodegraph
-void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBones,
- aiNode* pcParent,uint16_t iParentIndex)
-{
- ai_assert(NULL != apcBones && NULL != pcParent);
-
- // get a pointer to the header ...
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
-
- const MDL::IntBone_MDL7** apcBones2 = apcBones;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
-
- const MDL::IntBone_MDL7* const pcBone = *apcBones2++;
- if (pcBone->iParent == iParentIndex) {
- ++pcParent->mNumChildren;
- }
- }
- pcParent->mChildren = new aiNode*[pcParent->mNumChildren];
- unsigned int qq = 0;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
-
- const MDL::IntBone_MDL7* const pcBone = *apcBones++;
- if (pcBone->iParent != iParentIndex)continue;
-
- aiNode* pcNode = pcParent->mChildren[qq++] = new aiNode();
- pcNode->mName = aiString( pcBone->mName );
-
- AddBonesToNodeGraph_3DGS_MDL7(apcBones,pcNode,(uint16_t)i);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output animations
-void MDLImporter::BuildOutputAnims_3DGS_MDL7(
- const MDL::IntBone_MDL7** apcBonesOut)
-{
- ai_assert(NULL != apcBonesOut);
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)mBuffer;
-
- // one animation ...
- aiAnimation* pcAnim = new aiAnimation();
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
- if (!apcBonesOut[i]->pkeyPositions.empty()) {
-
- // get the last frame ... (needn't be equal to pcHeader->frames_num)
- for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size();++qq) {
- pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
- apcBonesOut[i]->pkeyPositions[qq].mTime);
- }
- ++pcAnim->mNumChannels;
- }
- }
- if (pcAnim->mDuration) {
- pcAnim->mChannels = new aiNodeAnim*[pcAnim->mNumChannels];
-
- unsigned int iCnt = 0;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
- if (!apcBonesOut[i]->pkeyPositions.empty()) {
- const MDL::IntBone_MDL7* const intBone = apcBonesOut[i];
-
- aiNodeAnim* const pcNodeAnim = pcAnim->mChannels[iCnt++] = new aiNodeAnim();
- pcNodeAnim->mNodeName = aiString( intBone->mName );
-
- // allocate enough storage for all keys
- pcNodeAnim->mNumPositionKeys = (unsigned int)intBone->pkeyPositions.size();
- pcNodeAnim->mNumScalingKeys = (unsigned int)intBone->pkeyPositions.size();
- pcNodeAnim->mNumRotationKeys = (unsigned int)intBone->pkeyPositions.size();
-
- pcNodeAnim->mPositionKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
- pcNodeAnim->mScalingKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
- pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys];
-
- // copy all keys
- for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq) {
- pcNodeAnim->mPositionKeys[qq] = intBone->pkeyPositions[qq];
- pcNodeAnim->mScalingKeys[qq] = intBone->pkeyScalings[qq];
- pcNodeAnim->mRotationKeys[qq] = intBone->pkeyRotations[qq];
- }
- }
- }
-
- // store the output animation
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- pScene->mAnimations[0] = pcAnim;
- }
- else delete pcAnim;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
- const MDL::BoneTransform_MDL7* pcBoneTransforms,
- MDL::IntBone_MDL7** apcBonesOut)
-{
- ai_assert(NULL != pcBoneTransforms);
- ai_assert(NULL != apcBonesOut);
-
- // first .. get the transformation matrix
- aiMatrix4x4 mTransform;
- mTransform.a1 = pcBoneTransforms->m[0];
- mTransform.b1 = pcBoneTransforms->m[1];
- mTransform.c1 = pcBoneTransforms->m[2];
- mTransform.d1 = pcBoneTransforms->m[3];
-
- mTransform.a2 = pcBoneTransforms->m[4];
- mTransform.b2 = pcBoneTransforms->m[5];
- mTransform.c2 = pcBoneTransforms->m[6];
- mTransform.d2 = pcBoneTransforms->m[7];
-
- mTransform.a3 = pcBoneTransforms->m[8];
- mTransform.b3 = pcBoneTransforms->m[9];
- mTransform.c3 = pcBoneTransforms->m[10];
- mTransform.d3 = pcBoneTransforms->m[11];
-
- // now decompose the transformation matrix into separate
- // scaling, rotation and translation
- aiVectorKey vScaling,vPosition;
- aiQuatKey qRotation;
-
- // FIXME: Decompose will assert in debug builds if the matrix is invalid ...
- mTransform.Decompose(vScaling.mValue,qRotation.mValue,vPosition.mValue);
-
- // now generate keys
- vScaling.mTime = qRotation.mTime = vPosition.mTime = (double)iTrafo;
-
- // add the keys to the bone
- MDL::IntBone_MDL7* const pcBoneOut = apcBonesOut[pcBoneTransforms->bone_index];
- pcBoneOut->pkeyPositions.push_back ( vPosition );
- pcBoneOut->pkeyScalings.push_back ( vScaling );
- pcBoneOut->pkeyRotations.push_back ( qRotation );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct output meshes
-void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplittedGroupData_MDL7& splittedGroupData)
-{
- const MDL::IntSharedData_MDL7& shared = splittedGroupData.shared;
-
- // get a pointer to the header ...
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- const unsigned int iNumOutBones = pcHeader->bones_num;
-
- for (std::vector<MaterialHelper*>::size_type i = 0; i < shared.pcMats.size();++i) {
- if (!splittedGroupData.aiSplit[i]->empty()) {
-
- // allocate the output mesh
- aiMesh* pcMesh = new aiMesh();
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mMaterialIndex = (unsigned int)i;
-
- // allocate output storage
- pcMesh->mNumFaces = (unsigned int)splittedGroupData.aiSplit[i]->size();
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- pcMesh->mNumVertices = pcMesh->mNumFaces*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- if (!groupData.vTextureCoords1.empty()) {
- pcMesh->mNumUVComponents[0] = 2;
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- if (!groupData.vTextureCoords2.empty()) {
- pcMesh->mNumUVComponents[1] = 2;
- pcMesh->mTextureCoords[1] = new aiVector3D[pcMesh->mNumVertices];
- }
- }
-
- // iterate through all faces and build an unique set of vertices
- unsigned int iCurrent = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
- pcMesh->mFaces[iFace].mNumIndices = 3;
- pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
-
- unsigned int iSrcFace = splittedGroupData.aiSplit[i]->operator[](iFace);
- const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
-
- // iterate through all face indices
- for (unsigned int c = 0; c < 3;++c) {
- const uint32_t iIndex = oldFace.mIndices[c];
- pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex];
- pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex];
-
- if (!groupData.vTextureCoords1.empty()) {
-
- pcMesh->mTextureCoords[0][iCurrent] = groupData.vTextureCoords1[iIndex];
- if (!groupData.vTextureCoords2.empty()) {
- pcMesh->mTextureCoords[1][iCurrent] = groupData.vTextureCoords2[iIndex];
- }
- }
- pcMesh->mFaces[iFace].mIndices[c] = iCurrent++;
- }
- }
-
- // if we have bones in the mesh we'll need to generate
- // proper vertex weights for them
- if (!groupData.aiBones.empty()) {
- std::vector<std::vector<unsigned int> > aaiVWeightList;
- aaiVWeightList.resize(iNumOutBones);
-
- int iCurrent = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
- unsigned int iSrcFace = splittedGroupData.aiSplit[i]->operator[](iFace);
- const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
-
- // iterate through all face indices
- for (unsigned int c = 0; c < 3;++c) {
- unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ];
- if (0xffffffff != iBone) {
- if (iBone >= iNumOutBones) {
- DefaultLogger::get()->error("Bone index overflow. "
- "The bone index of a vertex exceeds the allowed range. ");
- iBone = iNumOutBones-1;
- }
- aaiVWeightList[ iBone ].push_back ( iCurrent );
- }
- ++iCurrent;
- }
- }
- // now check which bones are required ...
- for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k != aaiVWeightList.end();++k) {
- if (!(*k).empty()) {
- ++pcMesh->mNumBones;
- }
- }
- pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
- iCurrent = 0;
- for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k!= aaiVWeightList.end();++k,++iCurrent)
- {
- if ((*k).empty())
- continue;
-
- // seems we'll need this node
- aiBone* pcBone = pcMesh->mBones[ iCurrent ] = new aiBone();
- pcBone->mName = aiString(shared.apcOutBones[ iCurrent ]->mName);
- pcBone->mOffsetMatrix = shared.apcOutBones[ iCurrent ]->mOffsetMatrix;
-
- // setup vertex weights
- pcBone->mNumWeights = (unsigned int)(*k).size();
- pcBone->mWeights = new aiVertexWeight[pcBone->mNumWeights];
-
- for (unsigned int weight = 0; weight < pcBone->mNumWeights;++weight) {
- pcBone->mWeights[weight].mVertexId = (*k)[weight];
- pcBone->mWeights[weight].mWeight = 1.0f;
- }
- }
- }
- // add the mesh to the list of output meshes
- splittedGroupData.avOutList.push_back(pcMesh);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Join to materials
-void MDLImporter::JoinSkins_3DGS_MDL7(
- MaterialHelper* pcMat1,
- MaterialHelper* pcMat2,
- MaterialHelper* pcMatOut)
-{
- ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
-
- // first create a full copy of the first skin property set
- // and assign it to the output material
- MaterialHelper::CopyPropertyList(pcMatOut,pcMat1);
-
- int iVal = 0;
- pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
-
- // then extract the diffuse texture from the second skin,
- // setup 1 as UV source and we have it
- aiString sString;
- if (AI_SUCCESS == aiGetMaterialString ( pcMat2, AI_MATKEY_TEXTURE_DIFFUSE(0),&sString )) {
- iVal = 1;
- pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
- pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a half-life 2 MDL
-void MDLImporter::InternReadFile_HL2( )
-{
- //const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
- throw DeadlyImportError("HL2 MDLs are not implemented");
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
diff --git a/3rdparty/assimp/code/MDLLoader.h b/3rdparty/assimp/code/MDLLoader.h
deleted file mode 100644
index 4d065464..00000000
--- a/3rdparty/assimp/code/MDLLoader.h
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file MDLLoader.h
- * @brief Declaration of the loader for MDL files
- */
-
-#ifndef AI_MDLLOADER_H_INCLUDED
-#define AI_MDLLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-
-struct aiNode;
-#include "MDLFileData.h"
-#include "HalfLifeFileData.h"
-
-namespace Assimp {
-class MaterialHelper;
-
-using namespace MDL;
-
-// --------------------------------------------------------------------------------------
-// Include file/line information in debug builds
-#ifdef ASSIMP_BUILD_DEBUG
-# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg,__FILE__,__LINE__)
-#else
-# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg)
-#endif
-
-// --------------------------------------------------------------------------------------
-/** @brief Class to load MDL files.
- *
- * Several subformats exist:
- * <ul>
- * <li>Quake I</li>
- * <li>3D Game Studio MDL3, MDL4</li>
- * <li>3D Game Studio MDL5</li>
- * <li>3D Game Studio MDL7</li>
- * <li>Halflife 2</li>
- * </ul>
- * These formats are partially identical and it would be possible to load
- * them all with a single 1000-line function-beast. However, it has been
- * splitted to several code paths to make the code easier to read and maintain.
-*/
-class MDLImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- MDLImporter();
-
- /** Destructor, private as well */
- ~MDLImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Import a quake 1 MDL file (IDPO)
- */
- void InternReadFile_Quake1( );
-
- // -------------------------------------------------------------------
- /** Import a GameStudio A4/A5 file (MDL 3,4,5)
- */
- void InternReadFile_3DGS_MDL345( );
-
- // -------------------------------------------------------------------
- /** Import a GameStudio A7 file (MDL 7)
- */
- void InternReadFile_3DGS_MDL7( );
-
- // -------------------------------------------------------------------
- /** Import a CS:S/HL2 MDL file (not fully implemented)
- */
- void InternReadFile_HL2( );
-
- // -------------------------------------------------------------------
- /** Check whether a given position is inside the valid range
- * Throw a DeadlyImportError if it is not
- * \param szPos Cursor position
- * \param szFile Name of the source file from which the function was called
- * \param iLine Source code line from which the function was called
- */
- void SizeCheck(const void* szPos);
- void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
-
-
- // -------------------------------------------------------------------
- /** Validate the header data structure of a game studio MDL7 file
- * \param pcHeader Input header to be validated
- */
- void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader);
-
- // -------------------------------------------------------------------
- /** Validate the header data structure of a Quake 1 model
- * \param pcHeader Input header to be validated
- */
- void ValidateHeader_Quake1(const MDL::Header* pcHeader);
-
-
- // -------------------------------------------------------------------
- /** Try to load a palette from the current directory (colormap.lmp)
- * If it is not found the default palette of Quake1 is returned
- */
- void SearchPalette(const unsigned char** pszColorMap);
-
- // -------------------------------------------------------------------
- /** Free a palette created with a previous call to SearchPalette()
- */
- void FreePalette(const unsigned char* pszColorMap);
-
-
- // -------------------------------------------------------------------
- /** Load a paletized texture from the file and convert it to 32bpp
- */
- void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
-
- // -------------------------------------------------------------------
- /** Used to load textures from MDL3/4
- * \param szData Input data
- * \param iType Color data type
- * \param piSkip Receive: Size to skip, in bytes
- */
- void CreateTexture_3DGS_MDL4(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip);
-
-
- // -------------------------------------------------------------------
- /** Used to load textures from MDL5
- * \param szData Input data
- * \param iType Color data type
- * \param piSkip Receive: Size to skip, in bytes
- */
- void CreateTexture_3DGS_MDL5(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip);
-
-
- // -------------------------------------------------------------------
- /** Checks whether a texture can be replaced with a single color
- * This is useful for all file formats before MDL7 (all those
- * that are not containing material colors separate from textures).
- * MED seems to write dummy 8x8 monochrome images instead.
- * \param pcTexture Input texture
- * \return aiColor.r is set to qnan if the function fails and no
- * color can be found.
- */
- aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
-
-
- // -------------------------------------------------------------------
- /** Converts the absolute texture coordinates in MDL5 files to
- * relative in a range between 0 and 1
- */
- void CalculateUVCoordinates_MDL5();
-
-
- // -------------------------------------------------------------------
- /** Read an UV coordinate from the file. If the file format is not
- * MDL5, the function calculates relative texture coordinates
- * \param vOut Receives the output UV coord
- * \param pcSrc UV coordinate buffer
- * \param UV coordinate index
- */
- void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut,
- const MDL::TexCoord_MDL3* pcSrc,
- unsigned int iIndex);
-
- // -------------------------------------------------------------------
- /** Setup the material properties for Quake and MDL<7 models.
- * These formats don't support more than one material per mesh,
- * therefore the method processes only ONE skin and removes
- * all others.
- */
- void SetupMaterialProperties_3DGS_MDL5_Quake1( );
-
-
- // -------------------------------------------------------------------
- /** Parse a skin lump in a MDL7/HMP7 file with all of its features
- * variant 1: Current cursor position is the beginning of the skin header
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer
- * \param pcMats Material list for this group. To be filled ...
- */
- void ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- std::vector<MaterialHelper*>& pcMats);
-
- // -------------------------------------------------------------------
- /** Parse a skin lump in a MDL7/HMP7 file with all of its features
- * variant 2: Current cursor position is the beginning of the skin data
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer
- * \param pcMatOut Output material
- * \param iType header.typ
- * \param iWidth header.width
- * \param iHeight header.height
- */
- void ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- MaterialHelper* pcMatOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight);
-
- // -------------------------------------------------------------------
- /** Skip a skin lump in a MDL7/HMP7 file
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer. Points to the byte just
- * behind the last byte of the skin.
- * \param iType header.typ
- * \param iWidth header.width
- * \param iHeight header.height
- */
- void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight);
-
- // -------------------------------------------------------------------
- /** Parse texture color data for MDL5, MDL6 and MDL7 formats
- * \param szData Current data pointer
- * \param iType type of the texture data. No DDS or external
- * \param piSkip Receive the number of bytes to skip
- * \param pcNew Must point to fully initialized data. Width and
- * height must be set. If pcNew->pcData is set to 0xffffffff,
- * piSkip will receive the size of the texture, in bytes, but no
- * color data will be read.
- */
- void ParseTextureColorData(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip,
- aiTexture* pcNew);
-
- // -------------------------------------------------------------------
- /** Join two materials / skins. Setup UV source ... etc
- * \param pcMat1 First input material
- * \param pcMat2 Second input material
- * \param pcMatOut Output material instance to be filled. Must be empty
- */
- void JoinSkins_3DGS_MDL7(MaterialHelper* pcMat1,
- MaterialHelper* pcMat2,
- MaterialHelper* pcMatOut);
-
- // -------------------------------------------------------------------
- /** Add a bone transformation key to an animation
- * \param iTrafo Index of the transformation (always==frame index?)
- * No need to validate this index, it is always valid.
- * \param pcBoneTransforms Bone transformation for this index
- * \param apcOutBones Output bones array
- */
- void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
- const MDL::BoneTransform_MDL7* pcBoneTransforms,
- MDL::IntBone_MDL7** apcBonesOut);
-
- // -------------------------------------------------------------------
- /** Load the bone list of a MDL7 file
- * \return If the bones could be loaded successfully, a valid
- * array containing pointers to a temporary bone
- * representation. NULL if the bones could not be loaded.
- */
- MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
-
- // -------------------------------------------------------------------
- /** Load bone transformation keyframes from a file chunk
- * \param groupInfo -> doc of data structure
- * \param frame -> doc of data structure
- * \param shared -> doc of data structure
- */
- void ParseBoneTrafoKeys_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- IntFrameInfo_MDL7& frame,
- MDL::IntSharedData_MDL7& shared);
-
- // -------------------------------------------------------------------
- /** Calculate absolute bone animation matrices for each bone
- * \param apcOutBones Output bones array
- */
- void CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones);
-
- // -------------------------------------------------------------------
- /** Add all bones to the nodegraph (as children of the root node)
- * \param apcBonesOut List of bones
- * \param pcParent Parent node. New nodes will be added to this node
- * \param iParentIndex Index of the parent bone
- */
- void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut,
- aiNode* pcParent,uint16_t iParentIndex);
-
- // -------------------------------------------------------------------
- /** Build output animations
- * \param apcBonesOut List of bones
- */
- void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut);
-
- // -------------------------------------------------------------------
- /** Handles materials that are just referencing another material
- * There is no test file for this feature, but Conitec's doc
- * say it is used.
- */
- void HandleMaterialReferences_3DGS_MDL7();
-
- // -------------------------------------------------------------------
- /** Copies only the material that are referenced by at least one
- * mesh to the final output material list. All other materials
- * will be discarded.
- * \param shared -> doc of data structure
- */
- void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared);
-
- // -------------------------------------------------------------------
- /** Process the frame section at the end of a group
- * \param groupInfo -> doc of data structure
- * \param shared -> doc of data structure
- * \param szCurrent Pointer to the start of the frame section
- * \param szCurrentOut Receives a pointer to the first byte of the
- * next data section.
- * \return false to read no further groups (a small workaround for
- * some tiny and unsolved problems ... )
- */
- bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSharedData_MDL7& shared,
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Sort all faces by their materials. If the mesh is using
- * multiple materials per face (that are blended together) the function
- * might create new materials.
- * \param groupInfo -> doc of data structure
- * \param groupData -> doc of data structure
- * \param splittedGroupData -> doc of data structure
- */
- void SortByMaterials_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplittedGroupData_MDL7& splittedGroupData);
-
- // -------------------------------------------------------------------
- /** Read all faces and vertices from a MDL7 group. The function fills
- * preallocated memory buffers.
- * \param groupInfo -> doc of data structure
- * \param groupData -> doc of data structure
- */
- void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData);
-
- // -------------------------------------------------------------------
- /** Generate the final output meshes for a7 models
- * \param groupData -> doc of data structure
- * \param splittedGroupData -> doc of data structure
- */
- void GenerateOutputMeshes_3DGS_MDL7(
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplittedGroupData_MDL7& splittedGroupData);
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Configuration option: palette to be used to decode palletized images*/
- std::string configPalette;
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** For GameStudio MDL files: The number in the magic word, either 3,4 or 5
- * (MDL7 doesn't need this, the format has a separate loader) */
- unsigned int iGSFileVersion;
-
- /** Output I/O handler. used to load external lmp files */
- IOSystem* pIOHandler;
-
- /** Output scene to be filled */
- aiScene* pScene;
-
- /** Size of the input file in bytes */
- unsigned int iFileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/MDLMaterialLoader.cpp b/3rdparty/assimp/code/MDLMaterialLoader.cpp
deleted file mode 100644
index 5ed30c30..00000000
--- a/3rdparty/assimp/code/MDLMaterialLoader.cpp
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the material part of the MDL importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-
-// internal headers
-#include "MDLLoader.h"
-#include "MDLDefaultColorMap.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Find a suitable pallette file or take teh default one
-void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
-{
- // now try to find the color map in the current directory
- IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
-
- const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
- if (pcStream)
- {
- if (pcStream->FileSize() >= 768)
- {
- szColorMap = new unsigned char[256*3];
- pcStream->Read(const_cast<unsigned char*>(szColorMap),256*3,1);
-
- DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
- "It will be used to decode embedded textures in palletized formats.");
- }
- delete pcStream;
- pcStream = NULL;
- }
- *pszColorMap = szColorMap;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Free the palette again
-void MDLImporter::FreePalette(const unsigned char* szColorMap)
-{
- if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
- delete[] szColorMap;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether we can replace a texture with a single color
-aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
-{
- ai_assert(NULL != pcTexture);
-
- aiColor4D clrOut;
- clrOut.r = get_qnan();
- if (!pcTexture->mHeight || !pcTexture->mWidth)
- return clrOut;
-
- const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
- const aiTexel* pcTexel = pcTexture->pcData+1;
- const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];
-
- while (pcTexel != pcTexelEnd)
- {
- if (*pcTexel != *(pcTexel-1))
- {
- pcTexel = NULL;
- break;
- }
- ++pcTexel;
- }
- if (pcTexel)
- {
- clrOut.r = pcTexture->pcData->r / 255.0f;
- clrOut.g = pcTexture->pcData->g / 255.0f;
- clrOut.b = pcTexture->pcData->b / 255.0f;
- clrOut.a = pcTexture->pcData->a / 255.0f;
- }
- return clrOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a texture from a MDL3 file
-void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
-{
- const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
-
- VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
- pcHeader->skinheight);
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
- pcNew->mWidth = pcHeader->skinwidth;
- pcNew->mHeight = pcHeader->skinheight;
-
- pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
-
- const unsigned char* szColorMap;
- this->SearchPalette(&szColorMap);
-
- // copy texture data
- for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char val = szData[i];
- const unsigned char* sz = &szColorMap[val*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = *sz++;
- pcNew->pcData[i].g = *sz++;
- pcNew->pcData[i].b = *sz;
- }
-
- FreePalette(szColorMap);
-
- // store the texture
- aiTexture** pc = this->pScene->mTextures;
- this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i <pScene->mNumTextures;++i)
- pScene->mTextures[i] = pc[i];
-
- pScene->mTextures[this->pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a texture from a MDL4 file
-void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip)
-{
- ai_assert(NULL != piSkip);
-
- const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
-
- if (iType == 1 || iType > 3)
- {
- DefaultLogger::get()->error("Unsupported texture file format");
- return;
- }
-
- bool bNoRead = *piSkip == 0xffffffff;
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
- pcNew->mWidth = pcHeader->skinwidth;
- pcNew->mHeight = pcHeader->skinheight;
-
- if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
- ParseTextureColorData(szData,iType,piSkip,pcNew);
-
- // store the texture
- if (!bNoRead)
- {
- if (!this->pScene->mNumTextures)
- {
- pScene->mNumTextures = 1;
- pScene->mTextures = new aiTexture*[1];
- pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = pScene->mTextures;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
- pScene->mTextures[i] = pc[i];
- pScene->mTextures[pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- }
- }
- else {
- pcNew->pcData = NULL;
- delete pcNew;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load color data of a texture and convert it to our output format
-void MDLImporter::ParseTextureColorData(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip,
- aiTexture* pcNew)
-{
- // allocate storage for the texture image
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
-
- // R5G6B5 format (with or without MIPs)
- // ****************************************************************
- if (2 == iType || 10 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);
-
- // copy texture data
- unsigned int i;
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
- AI_SWAP2(val);
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = (unsigned char)val.b << 3;
- pcNew->pcData[i].g = (unsigned char)val.g << 2;
- pcNew->pcData[i].b = (unsigned char)val.r << 3;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i * 2;
-
- // apply MIP maps
- if (10 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // ARGB4 format (with or without MIPs)
- // ****************************************************************
- else if (3 == iType || 11 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
-
- // copy texture data
- unsigned int i;
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
- AI_SWAP2(val);
-
- pcNew->pcData[i].a = (unsigned char)val.a << 4;
- pcNew->pcData[i].r = (unsigned char)val.r << 4;
- pcNew->pcData[i].g = (unsigned char)val.g << 4;
- pcNew->pcData[i].b = (unsigned char)val.b << 4;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i * 2;
-
- // apply MIP maps
- if (11 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // RGB8 format (with or without MIPs)
- // ****************************************************************
- else if (4 == iType || 12 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);
-
- // copy texture data
- unsigned int i;
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char* _szData = &szData[i*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].b = *_szData++;
- pcNew->pcData[i].g = *_szData++;
- pcNew->pcData[i].r = *_szData;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
-
-
- // apply MIP maps
- *piSkip = i * 3;
- if (12 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // ARGB8 format (with ir without MIPs)
- // ****************************************************************
- else if (5 == iType || 13 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
-
- // copy texture data
- unsigned int i;
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char* _szData = &szData[i*4];
-
- pcNew->pcData[i].b = *_szData++;
- pcNew->pcData[i].g = *_szData++;
- pcNew->pcData[i].r = *_szData++;
- pcNew->pcData[i].a = *_szData;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
-
- // apply MIP maps
- *piSkip = i << 2;
- if (13 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
- }
- }
- // palletized 8 bit texture. As for Quake 1
- // ****************************************************************
- else if (0 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);
-
- // copy texture data
- unsigned int i;
- if ((aiTexel*)0xffffffff != pcNew->pcData)
- {
-
- const unsigned char* szColorMap;
- this->SearchPalette(&szColorMap);
-
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char val = szData[i];
- const unsigned char* sz = &szColorMap[val*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = *sz++;
- pcNew->pcData[i].g = *sz++;
- pcNew->pcData[i].b = *sz;
- }
- this->FreePalette(szColorMap);
-
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i;
-
- // FIXME: Also support for MIP maps?
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a texture from a MDL5 file
-void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip)
-{
- ai_assert(NULL != piSkip);
- bool bNoRead = *piSkip == 0xffffffff;
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
-
- VALIDATE_FILE_SIZE(szData+8);
-
- // first read the size of the texture
- pcNew->mWidth = *((uint32_t*)szData);
- AI_SWAP4(pcNew->mWidth);
- szData += sizeof(uint32_t);
-
- pcNew->mHeight = *((uint32_t*)szData);
- AI_SWAP4(pcNew->mHeight);
- szData += sizeof(uint32_t);
-
- if (bNoRead)pcNew->pcData = (aiTexel*)0xffffffff;
-
- // this should not occur - at least the docs say it shouldn't
- // however, you can easily try out what MED does if you have
- // a model with a DDS texture and export it to MDL5 ...
- // yes, you're right. It embedds the DDS texture ... :cry:
- if (6 == iType)
- {
- // this is a compressed texture in DDS format
- *piSkip = pcNew->mWidth;
- VALIDATE_FILE_SIZE(szData + *piSkip);
-
- if (!bNoRead)
- {
- // place a hint and let the application know that it's
- // a DDS file
- pcNew->mHeight = 0;
- pcNew->achFormatHint[0] = 'd';
- pcNew->achFormatHint[1] = 'd';
- pcNew->achFormatHint[2] = 's';
- pcNew->achFormatHint[3] = '\0';
-
- pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
- ::memcpy(pcNew->pcData,szData,pcNew->mWidth);
- }
- }
- else
- {
- // parse the color data of the texture
- ParseTextureColorData(szData,iType,
- piSkip,pcNew);
- }
- *piSkip += sizeof(uint32_t) * 2;
-
- if (!bNoRead)
- {
- // store the texture
- if (!this->pScene->mNumTextures)
- {
- pScene->mNumTextures = 1;
- pScene->mTextures = new aiTexture*[1];
- pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = pScene->mTextures;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i < pScene->mNumTextures;++i)
- this->pScene->mTextures[i] = pc[i];
-
- pScene->mTextures[pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- }
- }
- else {
- pcNew->pcData = NULL;
- delete pcNew;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a skin from a MDL7 file - more complex than all other subformats
-void MDLImporter::ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- MaterialHelper* pcMatOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight)
-{
- aiTexture* pcNew = NULL;
-
- // get the type of the skin
- unsigned int iMasked = (unsigned int)(iType & 0xF);
-
- if (0x1 == iMasked)
- {
- // ***** REFERENCE TO ANOTHER SKIN INDEX *****
- int referrer = (int)iWidth;
- pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
- }
- else if (0x6 == iMasked)
- {
- // ***** EMBEDDED DDS FILE *****
- if (1 != iHeight)
- {
- DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
- "but texture height is not equal to 1, which is not supported by MED");
- }
-
- pcNew = new aiTexture();
- pcNew->mHeight = 0;
- pcNew->mWidth = iWidth;
-
- // place a proper format hint
- pcNew->achFormatHint[0] = 'd';
- pcNew->achFormatHint[1] = 'd';
- pcNew->achFormatHint[2] = 's';
- pcNew->achFormatHint[3] = '\0';
-
- pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
- memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
- szCurrent += iWidth;
- }
- if (0x7 == iMasked)
- {
- // ***** REFERENCE TO EXTERNAL FILE *****
- if (1 != iHeight)
- {
- DefaultLogger::get()->warn("Found a reference to an external texture, "
- "but texture height is not equal to 1, which is not supported by MED");
- }
-
- aiString szFile;
- const size_t iLen = strlen((const char*)szCurrent);
- size_t iLen2 = iLen+1;
- iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
- memcpy(szFile.data,(const char*)szCurrent,iLen2);
- szFile.length = iLen;
-
- szCurrent += iLen2;
-
- // place this as diffuse texture
- pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else if (iMasked || !iType || (iType && iWidth && iHeight))
- {
- // ***** STANDARD COLOR TEXTURE *****
- pcNew = new aiTexture();
- if (!iHeight || !iWidth)
- {
- DefaultLogger::get()->warn("Found embedded texture, but its width "
- "an height are both 0. Is this a joke?");
-
- // generate an empty chess pattern
- pcNew->mWidth = pcNew->mHeight = 8;
- pcNew->pcData = new aiTexel[64];
- for (unsigned int x = 0; x < 8;++x)
- {
- for (unsigned int y = 0; y < 8;++y)
- {
- const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
- (0 != x % 2 && 0 == y % 2));
-
- aiTexel* pc = &pcNew->pcData[y * 8 + x];
- pc->r = pc->b = pc->g = (bSet?0xFF:0);
- pc->a = 0xFF;
- }
- }
- }
- else
- {
- // it is a standard color texture. Fill in width and height
- // and call the same function we used for loading MDL5 files
-
- pcNew->mWidth = iWidth;
- pcNew->mHeight = iHeight;
-
- unsigned int iSkip = 0;
- this->ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
-
- // skip length of texture data
- szCurrent += iSkip;
- }
- }
-
- // sometimes there are MDL7 files which have a monochrome
- // texture instead of material colors ... posssible they have
- // been converted to MDL7 from other formats, such as MDL5
- aiColor4D clrTexture;
- if (pcNew)clrTexture = this->ReplaceTextureWithColor(pcNew);
- else clrTexture.r = get_qnan();
-
- // check whether a material definition is contained in the skin
- if (iType & AI_MDL7_SKINTYPE_MATERIAL)
- {
- BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
- szCurrent = (unsigned char*)(pcMatIn+1);
- VALIDATE_FILE_SIZE(szCurrent);
-
- aiColor3D clrTemp;
-
-#define COLOR_MULTIPLY_RGB() \
- if (is_not_qnan(clrTexture.r)) \
- { \
- clrTemp.r *= clrTexture.r; \
- clrTemp.g *= clrTexture.g; \
- clrTemp.b *= clrTexture.b; \
- }
-
- // read diffuse color
- clrTemp.r = pcMatIn->Diffuse.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Diffuse.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Diffuse.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // read specular color
- clrTemp.r = pcMatIn->Specular.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Specular.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Specular.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);
-
- // read ambient color
- clrTemp.r = pcMatIn->Ambient.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Ambient.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Ambient.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);
-
- // read emissive color
- clrTemp.r = pcMatIn->Emissive.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Emissive.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Emissive.b;
- AI_SWAP4(clrTemp.b);
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);
-
-#undef COLOR_MULITPLY_RGB
-
- // FIX: Take the opacity from the ambient color
- // the doc says something else, but it is fact that MED exports the
- // opacity like this .... ARRRGGHH!
- clrTemp.r = pcMatIn->Ambient.a;
- AI_SWAP4(clrTemp.r);
- if (is_not_qnan(clrTexture.r)) {
- clrTemp.r *= clrTexture.a;
- }
- pcMatOut->AddProperty<float>(&clrTemp.r,1,AI_MATKEY_OPACITY);
-
- // read phong power
- int iShadingMode = (int)aiShadingMode_Gouraud;
- AI_SWAP4(pcMatIn->Power);
- if (0.0f != pcMatIn->Power)
- {
- iShadingMode = (int)aiShadingMode_Phong;
- pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
- }
- pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
- }
- else if (is_not_qnan(clrTexture.r))
- {
- pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
- pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
- }
- // if the texture could be replaced by a single material color
- // we don't need the texture anymore
- if (is_not_qnan(clrTexture.r))
- {
- delete pcNew;
- pcNew = NULL;
- }
-
- // if an ASCII effect description (HLSL?) is contained in the file,
- // we can simply ignore it ...
- if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
- {
- VALIDATE_FILE_SIZE(szCurrent);
- int32_t iMe = *((int32_t*)szCurrent);
- AI_SWAP4(iMe);
- szCurrent += sizeof(char) * iMe + sizeof(int32_t);
- VALIDATE_FILE_SIZE(szCurrent);
- }
-
- // If an embedded texture has been loaded setup the corresponding
- // data structures in the aiScene instance
- if (pcNew && this->pScene->mNumTextures <= 999)
- {
-
- // place this as diffuse texture
- char szCurrent[5];
- ::sprintf(szCurrent,"*%i",this->pScene->mNumTextures);
-
- aiString szFile;
- const size_t iLen = strlen((const char*)szCurrent);
- ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
- szFile.length = iLen;
-
- pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // store the texture
- if (!this->pScene->mNumTextures)
- {
- this->pScene->mNumTextures = 1;
- this->pScene->mTextures = new aiTexture*[1];
- this->pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = this->pScene->mTextures;
- this->pScene->mTextures = new aiTexture*[this->pScene->mNumTextures+1];
- for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
- this->pScene->mTextures[i] = pc[i];
-
- this->pScene->mTextures[this->pScene->mNumTextures] = pcNew;
- this->pScene->mNumTextures++;
- delete[] pc;
- }
- }
- VALIDATE_FILE_SIZE(szCurrent);
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip a skin lump
-void MDLImporter::SkipSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight)
-{
- // get the type of the skin
- unsigned int iMasked = (unsigned int)(iType & 0xF);
-
- if (0x6 == iMasked)
- {
- szCurrent += iWidth;
- }
- if (0x7 == iMasked)
- {
- const size_t iLen = ::strlen((const char*)szCurrent);
- szCurrent += iLen+1;
- }
- else if (iMasked || !iType)
- {
- if (iMasked || !iType || (iType && iWidth && iHeight))
- {
- // ParseTextureColorData(..., aiTexture::pcData == 0xffffffff) will simply
- // return the size of the color data in bytes in iSkip
- unsigned int iSkip = 0;
-
- aiTexture tex;
- tex.pcData = reinterpret_cast<aiTexel*>(0xffffffff);
- tex.mHeight = iHeight;
- tex.mWidth = iWidth;
- this->ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);
-
- // FIX: Important, otherwise the destructor will crash
- tex.pcData = NULL;
-
- // skip length of texture data
- szCurrent += iSkip;
- }
- }
-
- // check whether a material definition is contained in the skin
- if (iType & AI_MDL7_SKINTYPE_MATERIAL)
- {
- BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
- szCurrent = (unsigned char*)(pcMatIn+1);
- }
-
- // if an ASCII effect description (HLSL?) is contained in the file,
- // we can simply ignore it ...
- if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
- {
- int32_t iMe = *((int32_t*)szCurrent);
- AI_SWAP4(iMe);
- szCurrent += sizeof(char) * iMe + sizeof(int32_t);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// What the fuck does this function do? Can't remember
-void MDLImporter::ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- std::vector<MaterialHelper*>& pcMats)
-{
- ai_assert(NULL != szCurrent);
- ai_assert(NULL != szCurrentOut);
-
- *szCurrentOut = szCurrent;
- BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent;
- AI_SWAP4(pcSkin->width);
- AI_SWAP4(pcSkin->height);
- szCurrent += 12;
-
- // allocate an output material
- MaterialHelper* pcMatOut = new MaterialHelper();
- pcMats.push_back(pcMatOut);
-
- // skip length of file name
- szCurrent += AI_MDL7_MAX_TEXNAMESIZE;
-
- ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
- pcSkin->typ,pcSkin->width,pcSkin->height);
-
- // place the name of the skin in the material
- if (pcSkin->texture_name[0])
- {
- // the 0 termination could be there or not - we can't know
- aiString szFile;
- ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
- szFile.data[sizeof(pcSkin->texture_name)] = '\0';
- szFile.length = ::strlen(szFile.data);
-
- pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
diff --git a/3rdparty/assimp/code/MS3DLoader.cpp b/3rdparty/assimp/code/MS3DLoader.cpp
deleted file mode 100644
index 26ec8922..00000000
--- a/3rdparty/assimp/code/MS3DLoader.cpp
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file MS3DLoader.cpp
- * @brief Implementation of the Ms3D importer class.
- * Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-
-// internal headers
-#include "MS3DLoader.h"
-#include "StreamReader.h"
-using namespace Assimp;
-
-// ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
-// (enable old code path, which generates extra nodes per mesh while
-// the newer code uses aiMesh::mName to express the name of the
-// meshes (a.k.a. groups in MS3D))
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MS3DImporter::MS3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MS3DImporter::~MS3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // first call - simple extension check
- const std::string extension = GetExtension(pFile);
- if (extension == "ms3d") {
- return true;
- }
-
- // second call - check for magic identifiers
- else if (!extension.length() || checkSig) {
- if (!pIOHandler) {
- return true;
- }
- const char* tokens[] = {"MS3D000000"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MS3DImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ms3d");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ReadColor(StreamReaderLE& stream, aiColor4D& ambient)
-{
- // aiColor4D is packed on gcc, implicit binding to float& fails therefore.
- stream >> (float&)ambient.r >> (float&)ambient.g >> (float&)ambient.b >> (float&)ambient.a;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ReadVector(StreamReaderLE& stream, aiVector3D& pos)
-{
- // See note in ReadColor()
- stream >> (float&)pos.x >> (float&)pos.y >> (float&)pos.z;
-}
-
-// ------------------------------------------------------------------------------------------------
-template<typename T>
-void MS3DImporter :: ReadComments(StreamReaderLE& stream, std::vector<T>& outp)
-{
- uint16_t cnt;
- stream >> cnt;
-
- for (unsigned int i = 0; i < cnt; ++i) {
- uint32_t index, clength;
- stream >> index >> clength;
-
- if (index >= outp.size()) {
- DefaultLogger::get()->warn("MS3D: Invalid index in comment section");
- }
- else if (clength > stream.GetRemainingSize()) {
- throw DeadlyImportError("MS3D: Failure reading comment, length field is out of range");
- }
- else {
- outp[index].comment = std::string(reinterpret_cast<char*>(stream.GetPtr()),clength);
- }
- stream.IncPtr(clength);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T, typename T2, typename T3> bool inrange(const T& in, const T2& lower, const T3& higher)
-{
- return in > lower && in <= higher;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints,
- std::vector<bool>& hadit,
- aiNode* nd,
- const aiMatrix4x4& absTrafo)
-{
- unsigned int cnt = 0;
- for (size_t i = 0; i < joints.size(); ++i) {
- if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
- ++cnt;
- }
- }
-
- nd->mChildren = new aiNode*[nd->mNumChildren = cnt];
- cnt = 0;
- for (size_t i = 0; i < joints.size(); ++i) {
- if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
- aiNode* ch = nd->mChildren[cnt++] = new aiNode(joints[i].name);
- ch->mParent = nd;
-
- ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())*
- // XXX actually, I don't *know* why we need the inverse here. Probably column vs. row order?
- aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation).Transpose();
-
- const aiMatrix4x4 abs = absTrafo*ch->mTransformation;
- for (unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
- aiMesh* const msh = mScene->mMeshes[a];
- for (unsigned int n = 0; n < msh->mNumBones; ++n) {
- aiBone* const bone = msh->mBones[n];
-
- if (bone->mName == ch->mName) {
- bone->mOffsetMatrix = aiMatrix4x4(abs).Inverse();
- }
- }
- }
-
- hadit[i] = true;
- CollectChildJoints(joints,hadit,ch,abs);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd)
-{
- std::vector<bool> hadit(joints.size(),false);
- aiMatrix4x4 trafo;
-
- CollectChildJoints(joints,hadit,nd,trafo);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MS3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
-
- // CanRead() should have done this already
- char head[10];
- int32_t version;
-
- mScene = pScene;
-
-
- // 1 ------------ read into temporary data structures mirroring the original file
-
- stream.CopyAndAdvance(head,10);
- stream >> version;
- if (strncmp(head,"MS3D000000",10)) {
- throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: "+pFile);
- }
-
- if (version != 4) {
- throw DeadlyImportError("MS3D: Unsupported file format version, 4 was expected");
- }
-
- uint16_t verts;
- stream >> verts;
-
- std::vector<TempVertex> vertices(verts);
- for (unsigned int i = 0; i < verts; ++i) {
- TempVertex& v = vertices[i];
-
- stream.IncPtr(1);
- ReadVector(stream,v.pos);
- v.bone_id[0] = stream.GetI1();
- v.ref_cnt = stream.GetI1();
-
- v.bone_id[1] = v.bone_id[2] = v.bone_id[3] = 0xffffffff;
- v.weights[1] = v.weights[2] = v.weights[3] = 0.f;
- v.weights[0] = 1.f;
- }
-
- uint16_t tris;
- stream >> tris;
-
- std::vector<TempTriangle> triangles(tris);
- for (unsigned int i = 0;i < tris; ++i) {
- TempTriangle& t = triangles[i];
-
- stream.IncPtr(2);
- for (unsigned int i = 0; i < 3; ++i) {
- t.indices[i] = stream.GetI2();
- }
-
- for (unsigned int i = 0; i < 3; ++i) {
- ReadVector(stream,t.normals[i]);
- }
-
- for (unsigned int i = 0; i < 3; ++i) {
- stream >> (float&)(t.uv[i].x); // see note in ReadColor()
- }
- for (unsigned int i = 0; i < 3; ++i) {
- stream >> (float&)(t.uv[i].y);
- }
-
- t.sg = stream.GetI1();
- t.group = stream.GetI1();
- }
-
- uint16_t grp;
- stream >> grp;
-
- bool need_default = false;
- std::vector<TempGroup> groups(grp);
- for (unsigned int i = 0;i < grp; ++i) {
- TempGroup& t = groups[i];
-
- stream.IncPtr(1);
- stream.CopyAndAdvance(t.name,32);
-
- t.name[32] = '\0';
- uint16_t num;
- stream >> num;
-
- t.triangles.resize(num);
- for (unsigned int i = 0; i < num; ++i) {
- t.triangles[i] = stream.GetI2();
- }
- t.mat = stream.GetI1();
- if (t.mat == 0xffffffff) {
- need_default = true;
- }
- }
-
- uint16_t mat;
- stream >> mat;
-
- std::vector<TempMaterial> materials(mat);
- for (unsigned int i = 0;i < mat; ++i) {
- TempMaterial& t = materials[i];
-
- stream.CopyAndAdvance(t.name,32);
- t.name[32] = '\0';
-
- ReadColor(stream,t.ambient);
- ReadColor(stream,t.diffuse);
- ReadColor(stream,t.specular);
- ReadColor(stream,t.emissive);
- stream >> t.shininess >> t.transparency;
-
- stream.IncPtr(1);
-
- stream.CopyAndAdvance(t.texture,128);
- t.texture[128] = '\0';
-
- stream.CopyAndAdvance(t.alphamap,128);
- t.alphamap[128] = '\0';
- }
-
- float animfps, currenttime;
- uint32_t totalframes;
- stream >> animfps >> currenttime >> totalframes;
-
- uint16_t joint;
- stream >> joint;
-
- std::vector<TempJoint> joints(joint);
- for (unsigned int i = 0; i < joint; ++i) {
- TempJoint& j = joints[i];
-
- stream.IncPtr(1);
- stream.CopyAndAdvance(j.name,32);
- j.name[32] = '\0';
-
- stream.CopyAndAdvance(j.parentName,32);
- j.parentName[32] = '\0';
-
- // DefaultLogger::get()->debug(j.name);
- // DefaultLogger::get()->debug(j.parentName);
-
- ReadVector(stream,j.rotation);
- ReadVector(stream,j.position);
-
- j.rotFrames.resize(stream.GetI2());
- j.posFrames.resize(stream.GetI2());
-
- for (unsigned int a = 0; a < j.rotFrames.size(); ++a) {
- TempKeyFrame& kf = j.rotFrames[a];
- stream >> kf.time;
- ReadVector(stream,kf.value);
- }
- for (unsigned int a = 0; a < j.posFrames.size(); ++a) {
- TempKeyFrame& kf = j.posFrames[a];
- stream >> kf.time;
- ReadVector(stream,kf.value);
- }
- }
-
- if (stream.GetRemainingSize() > 4) {
- uint32_t subversion;
- stream >> subversion;
- if (subversion == 1) {
- ReadComments<TempGroup>(stream,groups);
- ReadComments<TempMaterial>(stream,materials);
- ReadComments<TempJoint>(stream,joints);
-
- // model comment - print it for we have such a nice log.
- if (stream.GetI4()) {
- const size_t len = static_cast<size_t>(stream.GetI4());
- if (len > stream.GetRemainingSize()) {
- throw DeadlyImportError("MS3D: Model comment is too long");
- }
-
- const std::string& s = std::string(reinterpret_cast<char*>(stream.GetPtr()),len);
- DefaultLogger::get()->info(s);
- }
-
- if (stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) {
- for (unsigned int i = 0; i < verts; ++i) {
- TempVertex& v = vertices[i];
- v.weights[3]=1.f;
- for (unsigned int n = 0; n < 3; v.weights[3]-=v.weights[n++]) {
- v.bone_id[n+1] = stream.GetI1();
- v.weights[n] = static_cast<float>(static_cast<unsigned int>(stream.GetI1()))/255.f;
- }
- stream.IncPtr((subversion-1)<<2u);
- }
-
- // even further extra data is not of interest for us, at least now now.
- }
- }
- }
-
- // 2 ------------ convert to proper aiXX data structures -----------------------------------
-
- if (need_default && materials.size()) {
- DefaultLogger::get()->warn("MS3D: Found group with no material assigned, spawning default material");
- // if one of the groups has no material assigned, but there are other
- // groups with materials, a default material needs to be added (
- // scenepreprocessor adds a default material only if nummat==0).
- materials.push_back(TempMaterial());
- TempMaterial& m = materials.back();
-
- strcpy(m.name,"<MS3D_DefaultMat>");
- m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
- m.transparency = 1.f;
- m.shininess = 0.f;
-
- // this is because these TempXXX struct's have no c'tors.
- m.texture[0] = m.alphamap[0] = '\0';
-
- for (unsigned int i = 0; i < groups.size(); ++i) {
- TempGroup& g = groups[i];
- if (g.mat == 0xffffffff) {
- g.mat = materials.size()-1;
- }
- }
- }
-
- // convert materials to our generic key-value dict-alike
- if (materials.size()) {
- pScene->mMaterials = new aiMaterial*[materials.size()];
- for (size_t i = 0; i < materials.size(); ++i) {
-
- MaterialHelper* mo = new MaterialHelper();
- pScene->mMaterials[pScene->mNumMaterials++] = mo;
-
- const TempMaterial& mi = materials[i];
-
- aiString tmp;
- if (0[mi.alphamap]) {
- tmp = aiString(mi.alphamap);
- mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_OPACITY(0));
- }
- if (0[mi.texture]) {
- tmp = aiString(mi.texture);
- mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- if (0[mi.name]) {
- tmp = aiString(mi.name);
- mo->AddProperty(&tmp,AI_MATKEY_NAME);
- }
-
- mo->AddProperty(&mi.ambient,1,AI_MATKEY_COLOR_AMBIENT);
- mo->AddProperty(&mi.diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
- mo->AddProperty(&mi.specular,1,AI_MATKEY_COLOR_SPECULAR);
- mo->AddProperty(&mi.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
-
- mo->AddProperty(&mi.shininess,1,AI_MATKEY_SHININESS);
- mo->AddProperty(&mi.transparency,1,AI_MATKEY_OPACITY);
-
- const int sm = mi.shininess>0.f?aiShadingMode_Phong:aiShadingMode_Gouraud;
- mo->AddProperty(&sm,1,AI_MATKEY_SHADING_MODEL);
- }
- }
-
- // convert groups to meshes
- if (groups.empty()) {
- throw DeadlyImportError("MS3D: Didn't get any group records, file is malformed");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes=static_cast<unsigned int>(groups.size())]();
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
-
- aiMesh* m = pScene->mMeshes[i] = new aiMesh();
- const TempGroup& g = groups[i];
-
- if (pScene->mNumMaterials && g.mat > pScene->mNumMaterials) {
- throw DeadlyImportError("MS3D: Encountered invalid material index, file is malformed");
- } // no error if no materials at all - scenepreprocessor adds one then
-
- m->mMaterialIndex = g.mat;
- m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- m->mFaces = new aiFace[m->mNumFaces = g.triangles.size()];
- m->mNumVertices = m->mNumFaces*3;
-
- // storage for vertices - verbose format, as requested by the postprocessing pipeline
- m->mVertices = new aiVector3D[m->mNumVertices];
- m->mNormals = new aiVector3D[m->mNumVertices];
- m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
- m->mNumUVComponents[0] = 2;
-
- typedef std::map<unsigned int,unsigned int> BoneSet;
- BoneSet mybones;
-
- for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
- aiFace& f = m->mFaces[i];
- if (g.triangles[i]>triangles.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
- }
-
- TempTriangle& t = triangles[g.triangles[i]];
- f.mIndices = new unsigned int[f.mNumIndices=3];
-
- for (unsigned int i = 0; i < 3; ++i,++n) {
- if (t.indices[i]>vertices.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
- }
-
- const TempVertex& v = vertices[t.indices[i]];
- for (unsigned int a = 0; a < 4; ++a) {
- if (v.bone_id[a] != 0xffffffff) {
- if (v.bone_id[a] >= joints.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid bone index, file is malformed");
- }
- if (mybones.find(v.bone_id[a]) == mybones.end()) {
- mybones[v.bone_id[a]] = 1;
- }
- else ++mybones[v.bone_id[a]];
- }
- }
-
- // collect vertex components
- m->mVertices[n] = v.pos;
-
- m->mNormals[n] = t.normals[i];
- m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0);
- f.mIndices[i] = n;
- }
- }
-
- // allocate storage for bones
- if (mybones.size()) {
- std::vector<unsigned int> bmap(joints.size());
- m->mBones = new aiBone*[mybones.size()]();
- for (BoneSet::const_iterator it = mybones.begin(); it != mybones.end(); ++it) {
- aiBone* const bn = m->mBones[m->mNumBones] = new aiBone();
- const TempJoint& jnt = joints[(*it).first];
-
- bn->mName.Set(jnt.name);
- bn->mWeights = new aiVertexWeight[(*it).second];
-
- bmap[(*it).first] = m->mNumBones++;
- }
-
- // .. and collect bone weights
- for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
- TempTriangle& t = triangles[g.triangles[i]];
-
- for (unsigned int i = 0; i < 3; ++i,++n) {
- const TempVertex& v = vertices[t.indices[i]];
- for (unsigned int a = 0; a < 4; ++a) {
- const unsigned int bone = v.bone_id[a];
- if (bone==0xffffffff){
- continue;
- }
-
- aiBone* const outbone = m->mBones[bmap[bone]];
- aiVertexWeight& outwght = outbone->mWeights[outbone->mNumWeights++];
-
- outwght.mVertexId = n;
- outwght.mWeight = v.weights[a];
- }
- }
- }
- }
- }
-
- // ... add dummy nodes under a single root, each holding a reference to one
- // mesh. If we didn't do this, we'd loose the group name.
- aiNode* rt = pScene->mRootNode = new aiNode("<MS3DRoot>");
-
-#ifdef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
- rt->mChildren = new aiNode*[rt->mNumChildren=pScene->mNumMeshes+(joints.size()?1:0)]();
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- aiNode* nd = rt->mChildren[i] = new aiNode();
-
- const TempGroup& g = groups[i];
-
- // we need to generate an unique name for all mesh nodes.
- // since we want to keep the group name, a prefix is
- // prepended.
- nd->mName = aiString("<MS3DMesh>_");
- nd->mName.Append(g.name);
- nd->mParent = rt;
-
- nd->mMeshes = new unsigned int[nd->mNumMeshes = 1];
- nd->mMeshes[0] = i;
- }
-#else
- rt->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- rt->mMeshes[rt->mNumMeshes++] = i;
- }
-#endif
-
- // convert animations as well
- if (joints.size()) {
-#ifndef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
- rt->mChildren = new aiNode*[1]();
-#endif
- aiNode* jt = rt->mChildren[pScene->mNumMeshes] = new aiNode();
- jt->mParent = rt;
- CollectChildJoints(joints,jt);
- jt->mName.Set("<MS3DJointRoot>");
-
- pScene->mAnimations = new aiAnimation*[ pScene->mNumAnimations = 1 ];
- aiAnimation* const anim = pScene->mAnimations[0] = new aiAnimation();
-
- anim->mName.Set("<MS3DMasterAnim>");
-
- // carry the fps info to the user by scaling all times with it
- anim->mTicksPerSecond = animfps;
-
- // leave duration at its default, so ScenePreprocessor will fill an appropriate
- // value (the values taken from some MS3D files seem to be too unreliable
- // to pass the validation)
- // anim->mDuration = totalframes/animfps;
-
- anim->mChannels = new aiNodeAnim*[joints.size()]();
- for (std::vector<TempJoint>::const_iterator it = joints.begin(); it != joints.end(); ++it) {
- if ((*it).rotFrames.empty() && (*it).posFrames.empty()) {
- continue;
- }
-
- aiNodeAnim* nd = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nd->mNodeName.Set((*it).name);
-
- if ((*it).rotFrames.size()) {
- nd->mRotationKeys = new aiQuatKey[(*it).rotFrames.size()];
- for (std::vector<TempKeyFrame>::const_iterator rot = (*it).rotFrames.begin(); rot != (*it).rotFrames.end(); ++rot) {
- aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++];
-
- q.mTime = (*rot).time*animfps;
-
- // XXX it seems our matrix&quaternion code has faults in its conversion routines --
- // aiQuaternion(x,y,z) seems to besomething different as quat(matrix.fromeuler(x,y,z)).
- q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)*
- aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)).Transpose());
- }
- }
-
- if ((*it).posFrames.size()) {
- nd->mPositionKeys = new aiVectorKey[(*it).posFrames.size()];
-
- aiQuatKey* qu = nd->mRotationKeys;
- for (std::vector<TempKeyFrame>::const_iterator pos = (*it).posFrames.begin(); pos != (*it).posFrames.end(); ++pos,++qu) {
- aiVectorKey& v = nd->mPositionKeys[nd->mNumPositionKeys++];
-
- v.mTime = (*pos).time*animfps;
- v.mValue = (*it).position + (*pos).value;
- }
- }
- }
- // fixup to pass the validation if not a single animation channel is non-trivial
- if (!anim->mNumChannels) {
- anim->mChannels = NULL;
- }
- }
-}
-
-#endif
diff --git a/3rdparty/assimp/code/MS3DLoader.h b/3rdparty/assimp/code/MS3DLoader.h
deleted file mode 100644
index 391aec5a..00000000
--- a/3rdparty/assimp/code/MS3DLoader.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MS3DLoader.h
- * @brief Declaration of the MS3D importer class.
- */
-#ifndef AI_MS3DLOADER_H_INCLUDED
-#define AI_MS3DLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------------------
-/** Milkshape 3D importer implementation */
-// ----------------------------------------------------------------------------------------------
-class MS3DImporter
- : public BaseImporter
-{
- friend class Importer;
-
-protected:
-
- MS3DImporter();
- ~MS3DImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details */
- void GetExtensionList(std::set<std::string>& extensions);
-
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
-private:
-
- struct TempJoint;
- void CollectChildJoints(const std::vector<TempJoint>& joints, std::vector<bool>& hadit, aiNode* nd,const aiMatrix4x4& absTrafo);
- void CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd);
-
- template<typename T> void ReadComments(StreamReaderLE& stream, std::vector<T>& outp);
-private:
-
- aiScene* mScene;
-
-private:
-
- struct TempVertex
- {
- aiVector3D pos;
- unsigned int bone_id[4], ref_cnt;
- float weights[4];
- };
-
- struct TempTriangle
- {
- unsigned int indices[3];
- aiVector3D normals[3];
- aiVector2D uv[3];
-
- unsigned int sg, group;
- };
-
- struct TempGroup
- {
- char name[33]; // +0
- std::vector<unsigned int> triangles;
- unsigned int mat; // 0xff is no material
- std::string comment;
- };
-
- struct TempMaterial
- {
- // again, add an extra 0 character to all strings -
- char name[33];
- char texture[129];
- char alphamap[129];
-
- aiColor4D diffuse,specular,ambient,emissive;
- float shininess,transparency;
- std::string comment;
- };
-
- struct TempKeyFrame
- {
- float time;
- aiVector3D value;
- };
-
- struct TempJoint
- {
- char name[33];
- char parentName[33];
- aiVector3D rotation, position;
-
- std::vector<TempKeyFrame> rotFrames;
- std::vector<TempKeyFrame> posFrames;
- std::string comment;
- };
-
- //struct TempModel {
- // std::string comment;
- //};
-};
-
-}
-#endif
diff --git a/3rdparty/assimp/code/MakeVerboseFormat.cpp b/3rdparty/assimp/code/MakeVerboseFormat.cpp
deleted file mode 100644
index d4b3c712..00000000
--- a/3rdparty/assimp/code/MakeVerboseFormat.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file Implementation of the post processing step "MakeVerboseFormat"
-*/
-
-#include "AssimpPCH.h"
-#include "MakeVerboseFormat.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::MakeVerboseFormatProcess()
-{
- // nothing to do here
-}
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
-{
- // nothing to do here
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void MakeVerboseFormatProcess::Execute( aiScene* pScene)
-{
- ai_assert(NULL != pScene);
- DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if ( MakeVerboseFormat( pScene->mMeshes[a]))
- bHas = true;
- }
- if (bHas) DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
- else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
-
- pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
-
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
-{
- ai_assert(NULL != pcMesh);
-
- unsigned int iOldNumVertices = pcMesh->mNumVertices;
- const unsigned int iNumVerts = pcMesh->mNumFaces*3;
-
- aiVector3D* pvPositions = new aiVector3D[ iNumVerts ];
-
- aiVector3D* pvNormals = NULL;
- if (pcMesh->HasNormals())
- {
- pvNormals = new aiVector3D[iNumVerts];
- }
- aiVector3D* pvTangents = NULL, *pvBitangents = NULL;
- if (pcMesh->HasTangentsAndBitangents())
- {
- pvTangents = new aiVector3D[iNumVerts];
- pvBitangents = new aiVector3D[iNumVerts];
- }
-
- ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == 4);
- ai_assert(AI_MAX_NUMBER_OF_COLOR_SETS == 4);
-
- aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {NULL,NULL,NULL,NULL};
- aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {NULL,NULL,NULL,NULL};
-
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- apvTextureCoords[p++] = new aiVector3D[iNumVerts];
-
- p = 0;
- while (pcMesh->HasVertexColors(p))
- apvColorSets[p++] = new aiColor4D[iNumVerts];
-
- // allocate enough memory to hold output bones and vertex weights ...
- std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i) {
- newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
- }
-
- // iterate through all faces and build a clean list
- unsigned int iIndex = 0;
- for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
- {
- aiFace* pcFace = &pcMesh->mFaces[a];
- for (unsigned int q = 0; q < pcFace->mNumIndices;++q,++iIndex)
- {
- // need to build a clean list of bones, too
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
- {
- for (unsigned int a = 0; a < pcMesh->mBones[i]->mNumWeights;a++)
- {
- const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
- if (pcFace->mIndices[q] == w.mVertexId)
- {
- aiVertexWeight wNew;
- wNew.mVertexId = iIndex;
- wNew.mWeight = w.mWeight;
- newWeights[i].push_back(wNew);
- }
- }
- }
-
- pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
-
- if (pcMesh->HasNormals())
- {
- pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
- }
- if (pcMesh->HasTangentsAndBitangents())
- {
- pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
- pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
- }
-
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
- ++p;
- }
- p = 0;
- while (pcMesh->HasVertexColors(p))
- {
- apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
- ++p;
- }
- pcFace->mIndices[q] = iIndex;
- }
- }
-
- // build output vertex weights
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
- {
- delete pcMesh->mBones[i]->mWeights;
- if (!newWeights[i].empty())
- {
- pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
- memcpy(pcMesh->mBones[i]->mWeights,&newWeights[i][0],
- sizeof(aiVertexWeight) * newWeights[i].size());
- }
- else pcMesh->mBones[i]->mWeights = NULL;
- }
-
- // delete the old members
- delete[] pcMesh->mVertices;
- pcMesh->mVertices = pvPositions;
-
- p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- delete pcMesh->mTextureCoords[p];
- pcMesh->mTextureCoords[p] = apvTextureCoords[p];
- ++p;
- }
- p = 0;
- while (pcMesh->HasVertexColors(p))
- {
- delete pcMesh->mColors[p];
- pcMesh->mColors[p] = apvColorSets[p];
- ++p;
- }
- pcMesh->mNumVertices = iNumVerts;
-
- if (pcMesh->HasNormals())
- {
- delete[] pcMesh->mNormals;
- pcMesh->mNormals = pvNormals;
- }
- if (pcMesh->HasTangentsAndBitangents())
- {
- delete[] pcMesh->mTangents;
- pcMesh->mTangents = pvTangents;
- delete[] pcMesh->mBitangents;
- pcMesh->mBitangents = pvBitangents;
- }
- return (pcMesh->mNumVertices != iOldNumVertices);
-}
diff --git a/3rdparty/assimp/code/MakeVerboseFormat.h b/3rdparty/assimp/code/MakeVerboseFormat.h
deleted file mode 100644
index 6d480e5a..00000000
--- a/3rdparty/assimp/code/MakeVerboseFormat.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to bring a given scene
- into the verbose format that is expected by most postprocess steps.
- This is the inverse of the "JoinIdenticalVertices" step. */
-#ifndef AI_MAKEVERBOSEFORMAT_H_INC
-#define AI_MAKEVERBOSEFORMAT_H_INC
-
-#include "BaseProcess.h"
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** MakeVerboseFormatProcess: Class to convert an asset to the verbose
- * format which is expected by most postprocess steps.
- *
- * This is the inverse of what the "JoinIdenticalVertices" step is doing.
- * This step has no official flag (since it wouldn't make sense to run it
- * during import). It is intended for applications intending to modify the
- * returned aiScene. After this step has been executed, they can execute
- * other postprocess steps on the data. The code might also be useful to
- * quickly adapt code that doesn't result in a verbose representation of
- * the scene data.
- * The step has been added because it was required by the viewer, however
- * it has been moved to the main library since others might find it
- * useful, too. */
-class ASSIMP_API MakeVerboseFormatProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
-
- /** Constructor to be privately used by Importer, or by applications
- which know what they are doing if they modify the aiScene object */
- MakeVerboseFormatProcess();
-
- /** Destructor, private as well */
- ~MakeVerboseFormatProcess();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not */
- bool IsActive( unsigned int /*pFlags*/ ) const
- {
- // NOTE: There is no direct flag that corresponds to
- // this postprocess step.
- return false;
- }
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at. */
- void Execute( aiScene* pScene);
-
-
-private:
-
- //! Apply the postprocess step to a given submesh
- bool MakeVerboseFormat (aiMesh* pcMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_KILLNORMALPROCESS_H_INC
diff --git a/3rdparty/assimp/code/MaterialSystem.cpp b/3rdparty/assimp/code/MaterialSystem.cpp
deleted file mode 100644
index 4733d184..00000000
--- a/3rdparty/assimp/code/MaterialSystem.cpp
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MaterialSystem.cpp
- * @brief Implementation of the material system of the library
- */
-
-#include "AssimpPCH.h"
-
-#include "Hash.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Get a specific property from a material
-aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- const aiMaterialProperty** pPropOut)
-{
- ai_assert (pMat != NULL);
- ai_assert (pKey != NULL);
- ai_assert (pPropOut != NULL);
-
- /* Just search for a property with exactly this name ..
- * could be improved by hashing, but it's possibly
- * no worth the effort (we're bound to C structures,
- * thus std::map or derivates are not applicable. */
- for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
- aiMaterialProperty* prop = pMat->mProperties[i];
-
- if (prop /* just for safety ... */
- && 0 == strcmp( prop->mKey.data, pKey )
- && (0xffffffff == type || prop->mSemantic == type) /* 0xffffffff is a wildcard, but this is undocumented :-) */
- && (0xffffffff == index || prop->mIndex == index))
- {
- *pPropOut = pMat->mProperties[i];
- return AI_SUCCESS;
- }
- }
- *pPropOut = NULL;
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get an array of floating-point values from the material.
-aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- float* pOut,
- unsigned int* pMax)
-{
- ai_assert (pOut != NULL);
- ai_assert (pMat != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- // data is given in floats, simply copy it
- unsigned int iWrite;
- if ( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(float);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<float> ( reinterpret_cast<float*>(prop->mData)[a] );
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // data is given in ints, convert to float
- else if ( aiPTI_Integer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(int32_t);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<float> ( reinterpret_cast<int32_t*>(prop->mData)[a] );
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // a string ... read floats separated by spaces
- else {
- if (pMax) {
- iWrite = *pMax;
- }
- // strings are zero-terminated with a 32 bit length prefix, so this is safe
- const char* cur = prop->mData+4;
- ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
- for (unsigned int a = 0; ;++a) {
- cur = fast_atof_move(cur,pOut[a]);
- if (a==iWrite-1) {
- break;
- }
- if (!IsSpace(*cur)) {
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " is a string; failed to parse a float array out of it.");
- return AI_FAILURE;
- }
- }
-
- if (pMax) {
- *pMax = iWrite;
- }
- }
- return AI_SUCCESS;
-
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get an array if integers from the material
-aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- int* pOut,
- unsigned int* pMax)
-{
- ai_assert (pOut != NULL);
- ai_assert (pMat != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- // data is given in ints, simply copy it
- unsigned int iWrite;
- if ( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(int32_t);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]);
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // data is given in floats convert to int
- else if ( aiPTI_Float == prop->mType) {
- iWrite = prop->mDataLength / sizeof(float);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<int>(reinterpret_cast<float*>(prop->mData)[a]);
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // it is a string ... no way to read something out of this
- else {
- if (pMax) {
- iWrite = *pMax;
- }
- // strings are zero-terminated with a 32 bit length prefix, so this is safe
- const char* cur = prop->mData+4;
- ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
- for (unsigned int a = 0; ;++a) {
- pOut[a] = strtol10s(cur,&cur);
- if (a==iWrite-1) {
- break;
- }
- if (!IsSpace(*cur)) {
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " is a string; failed to parse an integer array out of it.");
- return AI_FAILURE;
- }
- }
-
- if (pMax) {
- *pMax = iWrite;
- }
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a color (3 or 4 floats) from the material
-aiReturn aiGetMaterialColor(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiColor4D* pOut)
-{
- unsigned int iMax = 4;
- const aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax);
-
- // if no alpha channel is defined: set it to 1.0
- if (3 == iMax) {
- pOut->a = 1.0f;
- }
-
- return eRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a string from the material
-aiReturn aiGetMaterialString(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiString* pOut)
-{
- ai_assert (pOut != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- if ( aiPTI_String == prop->mType) {
- ai_assert(prop->mDataLength>=5);
-
- // The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
- pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
-
- ai_assert(pOut->length+1+4==prop->mDataLength && !prop->mData[prop->mDataLength-1]);
- memcpy(pOut->data,prop->mData+4,pOut->length+1);
- }
- else {
- // TODO - implement lexical cast as well
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " was found, but is no string" );
- return AI_FAILURE;
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the number of textures on a particular texture stack
-ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
- C_ENUM aiTextureType type)
-{
- ai_assert (pMat != NULL);
-
- /* Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again) */
- unsigned int max = 0;
- for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
- aiMaterialProperty* prop = pMat->mProperties[i];
-
- if (prop /* just a sanity check ... */
- && 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
- && prop->mSemantic == type) {
-
- max = std::max(max,prop->mIndex+1);
- }
- }
- return max;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
- aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* _mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- float* blend /*= NULL*/,
- aiTextureOp* op /*= NULL*/,
- aiTextureMapMode* mapmode /*= NULL*/,
- unsigned int* flags /*= NULL*/
- )
-{
- ai_assert(NULL != mat && NULL != path);
-
- // Get the path to the texture
- if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
- return AI_FAILURE;
- }
- // Determine mapping type
- aiTextureMapping mapping = aiTextureMapping_UV;
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
- if (_mapping)
- *_mapping = mapping;
-
- // Get UV index
- if (aiTextureMapping_UV == mapping && uvindex) {
- aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex);
- }
- // Get blend factor
- if (blend) {
- aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend);
- }
- // Get texture operation
- if (op){
- aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op);
- }
- // Get texture mapping modes
- if (mapmode) {
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]);
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]);
- }
- // Get texture flags
- if (flags){
- aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construction. Actually the one and only way to get an aiMaterial instance
-MaterialHelper::MaterialHelper()
-{
- // Allocate 5 entries by default
- mNumProperties = 0;
- mNumAllocated = 5;
- mProperties = new aiMaterialProperty*[5];
-}
-
-// ------------------------------------------------------------------------------------------------
-MaterialHelper::~MaterialHelper()
-{
- _InternDestruct();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial::~aiMaterial()
-{
- // HACK (Aramis): This is safe: aiMaterial has a private constructor,
- // so instances must be created indirectly via MaterialHelper. We can't
- // use a virtual d'tor because we need to preserve binary compatibility
- // with good old C ...
- ((MaterialHelper*)this)->_InternDestruct();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Manual destructor
-void MaterialHelper::_InternDestruct()
-{
- // First clean up all properties
- Clear();
-
- // Then delete the array that stored them
- delete[] mProperties;
- AI_DEBUG_INVALIDATE_PTR(mProperties);
-
- // Update members
- mNumAllocated = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MaterialHelper::Clear()
-{
- for (unsigned int i = 0; i < mNumProperties;++i) {
- // delete this entry
- delete mProperties[i];
- AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
- }
- mNumProperties = 0;
-
- // The array remains allocated, we just invalidated its contents
-}
-
-// ------------------------------------------------------------------------------------------------
-uint32_t MaterialHelper::ComputeHash(bool includeMatName /*= false*/)
-{
- uint32_t hash = 1503; // magic start value, choosen to be my birthday :-)
- for (unsigned int i = 0; i < mNumProperties;++i) {
- aiMaterialProperty* prop;
-
- // Exclude all properties whose first character is '?' from the hash
- // See doc for aiMaterialProperty.
- if ((prop = mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) {
-
- hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
- hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
-
- // Combine the semantic and the index with the hash
- hash = SuperFastHash((const char*)&prop->mSemantic,sizeof(unsigned int),hash);
- hash = SuperFastHash((const char*)&prop->mIndex,sizeof(unsigned int),hash);
- }
- }
- return hash;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn MaterialHelper::RemoveProperty (const char* pKey,unsigned int type,
- unsigned int index
- )
-{
- ai_assert(NULL != pKey);
-
- for (unsigned int i = 0; i < mNumProperties;++i) {
- aiMaterialProperty* prop = mProperties[i];
-
- if (prop && !strcmp( prop->mKey.data, pKey ) &&
- prop->mSemantic == type && prop->mIndex == index)
- {
- // Delete this entry
- delete mProperties[i];
-
- // collapse the array behind --.
- --mNumProperties;
- for (unsigned int a = i; a < mNumProperties;++a) {
- mProperties[a] = mProperties[a+1];
- }
- return AI_SUCCESS;
- }
- }
-
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
- unsigned int pSizeInBytes,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiPropertyTypeInfo pType
- )
-{
- ai_assert (pInput != NULL);
- ai_assert (pKey != NULL);
- ai_assert (0 != pSizeInBytes);
-
- // first search the list whether there is already an entry with this key
- unsigned int iOutIndex = 0xffffffff;
- for (unsigned int i = 0; i < mNumProperties;++i) {
- aiMaterialProperty* prop = mProperties[i];
-
- if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
- prop->mSemantic == type && prop->mIndex == index){
-
- delete mProperties[i];
- iOutIndex = i;
- }
- }
-
- // Allocate a new material property
- aiMaterialProperty* pcNew = new aiMaterialProperty();
-
- // .. and fill it
- pcNew->mType = pType;
- pcNew->mSemantic = type;
- pcNew->mIndex = index;
-
- pcNew->mDataLength = pSizeInBytes;
- pcNew->mData = new char[pSizeInBytes];
- memcpy (pcNew->mData,pInput,pSizeInBytes);
-
- pcNew->mKey.length = ::strlen(pKey);
- ai_assert ( MAXLEN > pcNew->mKey.length);
- strcpy( pcNew->mKey.data, pKey );
-
- if (0xffffffff != iOutIndex) {
- mProperties[iOutIndex] = pcNew;
- return AI_SUCCESS;
- }
-
- // resize the array ... double the storage allocated
- if (mNumProperties == mNumAllocated) {
- const unsigned int iOld = mNumAllocated;
- mNumAllocated *= 2;
-
- aiMaterialProperty** ppTemp;
- try {
- ppTemp = new aiMaterialProperty*[mNumAllocated];
- } catch (std::bad_alloc&) {
- return AI_OUTOFMEMORY;
- }
-
- // just copy all items over; then replace the old array
- memcpy (ppTemp,mProperties,iOld * sizeof(void*));
-
- delete[] mProperties;
- mProperties = ppTemp;
- }
- // push back ...
- mProperties[mNumProperties++] = pcNew;
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn MaterialHelper::AddProperty (const aiString* pInput,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- // We don't want to add the whole buffer .. write a 32 bit length
- // prefix followed by the zero-terminated UTF8 string.
- // (HACK) I don't want to break the ABI now, but we definitely
- // ought to change aiString::mLength to uint32_t one day.
- if (sizeof(size_t) == 8) {
- aiString copy = *pInput;
- uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
- s[1] = static_cast<uint32_t>(pInput->length);
-
- return AddBinaryProperty(s+1,
- pInput->length+1+4,
- pKey,
- type,
- index,
- aiPTI_String);
- }
- ai_assert(sizeof(size_t)==4);
- return AddBinaryProperty(pInput,
- pInput->length+1+4,
- pKey,
- type,
- index,
- aiPTI_String);
-}
-
-// ------------------------------------------------------------------------------------------------
-void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest,
- const MaterialHelper* pcSrc
- )
-{
- ai_assert(NULL != pcDest);
- ai_assert(NULL != pcSrc);
-
- unsigned int iOldNum = pcDest->mNumProperties;
- pcDest->mNumAllocated += pcSrc->mNumAllocated;
- pcDest->mNumProperties += pcSrc->mNumProperties;
-
- aiMaterialProperty** pcOld = pcDest->mProperties;
- pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated];
-
- if (iOldNum && pcOld) {
- for (unsigned int i = 0; i < iOldNum;++i) {
- pcDest->mProperties[i] = pcOld[i];
- }
-
- delete[] pcOld;
- }
- for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) {
- aiMaterialProperty* propSrc = pcSrc->mProperties[i];
-
- // search whether we have already a property with this name -> if yes, overwrite it
- aiMaterialProperty* prop;
- for (unsigned int q = 0; q < iOldNum;++q) {
- prop = pcDest->mProperties[q];
- if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
- && prop->mIndex == propSrc->mIndex) {
- delete prop;
-
- // collapse the whole array ...
- memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q);
- i--;
- pcDest->mNumProperties--;
- }
- }
-
- // Allocate the output property and copy the source property
- prop = pcDest->mProperties[i] = new aiMaterialProperty();
- prop->mKey = propSrc->mKey;
- prop->mDataLength = propSrc->mDataLength;
- prop->mType = propSrc->mType;
- prop->mSemantic = propSrc->mSemantic;
- prop->mIndex = propSrc->mIndex;
-
- prop->mData = new char[propSrc->mDataLength];
- memcpy(prop->mData,propSrc->mData,prop->mDataLength);
- }
- return;
-}
-
diff --git a/3rdparty/assimp/code/MaterialSystem.h b/3rdparty/assimp/code/MaterialSystem.h
deleted file mode 100644
index ea8daf89..00000000
--- a/3rdparty/assimp/code/MaterialSystem.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MaterialSystem.h
- * Definition of the #MaterialHelper utility class.
- */
-#ifndef AI_MATERIALSYSTEM_H_INC
-#define AI_MATERIALSYSTEM_H_INC
-
-#include "../include/aiMaterial.h"
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------------
-/** Internal material helper class deriving from aiMaterial.
- *
- * Intended to be used to fill an aiMaterial structure more easily.
- */
-class ASSIMP_API MaterialHelper : public ::aiMaterial
-{
-public:
-
- // Construction and destruction
- MaterialHelper();
- ~MaterialHelper();
-
- // ------------------------------------------------------------------------------
- /** @brief Add a property with a given key and type info to the material
- * structure
- *
- * @param pInput Pointer to input data
- * @param pSizeInBytes Size of input data
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro
- * @param pType Type information hint
- */
- aiReturn AddBinaryProperty (const void* pInput,
- unsigned int pSizeInBytes,
- const char* pKey,
- unsigned int type ,
- unsigned int index ,
- aiPropertyTypeInfo pType);
-
- // ------------------------------------------------------------------------------
- /** @brief Add a string property with a given key and type info to the
- * material structure
- *
- * @param pInput Input string
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro
- */
- aiReturn AddProperty (const aiString* pInput,
- const char* pKey,
- unsigned int type = 0,
- unsigned int index = 0);
-
- // ------------------------------------------------------------------------------
- /** @brief Add a property with a given key to the material structure
- * @param pInput Pointer to the input data
- * @param pNumValues Number of values in the array
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro
- */
- template<class TYPE>
- aiReturn AddProperty (const TYPE* pInput,
- unsigned int pNumValues,
- const char* pKey,
- unsigned int type = 0,
- unsigned int index = 0);
-
- // ------------------------------------------------------------------------------
- /** @brief Remove a given key from the list.
- *
- * The function fails if the key isn't found
- * @param pKey Key to be deleted
- */
- aiReturn RemoveProperty (const char* pKey,
- unsigned int type = 0,
- unsigned int index = 0);
-
- // ------------------------------------------------------------------------------
- /** @brief Removes all properties from the material.
- *
- * The data array remains allocated so adding new properties is quite fast.
- */
- void Clear();
-
- // ------------------------------------------------------------------------------
- /** Computes a hash (hopefully unique) from all material properties
- * The hash value reflects the current property state, so if you add any
- * proprty and call this method again, the resulting hash value will be
- * different.
- *
- * @param includeMatName Set to 'true' to take all properties with
- * '?' as initial character in their name into account.
- * Currently #AI_MATKEY_NAME is the only example.
- * @return Unique hash
- */
- uint32_t ComputeHash(bool includeMatName = false);
-
- // ------------------------------------------------------------------------------
- /** Copy the property list of a material
- * @param pcDest Destination material
- * @param pcSrc Source material
- */
- static void CopyPropertyList(MaterialHelper* pcDest,
- const MaterialHelper* pcSrc);
-
-public:
- // For internal use. That's why it's public.
- void _InternDestruct();
-};
-
-
-// ----------------------------------------------------------------------------------------
-template<class TYPE>
-aiReturn MaterialHelper::AddProperty (const TYPE* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(TYPE),
- pKey,type,index,aiPTI_Buffer);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<float> (const float* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(float),
- pKey,type,index,aiPTI_Float);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<aiUVTransform> (const aiUVTransform* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(aiUVTransform),
- pKey,type,index,aiPTI_Float);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<aiColor4D> (const aiColor4D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(aiColor4D),
- pKey,type,index,aiPTI_Float);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<aiColor3D> (const aiColor3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(aiColor3D),
- pKey,type,index,aiPTI_Float);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<aiVector3D> (const aiVector3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(aiVector3D),
- pKey,type,index,aiPTI_Float);
-}
-
-// ----------------------------------------------------------------------------------------
-template<>
-inline aiReturn MaterialHelper::AddProperty<int> (const int* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(int),
- pKey,type,index,aiPTI_Integer);
-}
-} // ! namespace Assimp
-
-#endif //!! AI_MATERIALSYSTEM_H_INC
diff --git a/3rdparty/assimp/code/MemoryIOWrapper.h b/3rdparty/assimp/code/MemoryIOWrapper.h
deleted file mode 100644
index d34d987a..00000000
--- a/3rdparty/assimp/code/MemoryIOWrapper.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file MemoryIOWrapper.h
- * Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
-#ifndef AI_MEMORYIOSTREAM_H_INC
-#define AI_MEMORYIOSTREAM_H_INC
-namespace Assimp {
-#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
-#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
-
-// ----------------------------------------------------------------------------------
-/** Implementation of IOStream to read directly from a memory buffer */
-// ----------------------------------------------------------------------------------
-class MemoryIOStream : public IOStream
-{
- //friend class MemoryIOSystem;
-public:
- MemoryIOStream (const uint8_t* buff, size_t len)
- : buffer (buff), length(len), pos((size_t)0) {
- }
-
-public:
- ~MemoryIOStream () {
- }
-
- // -------------------------------------------------------------------
- // Read from stream
- size_t Read(void* pvBuffer, size_t pSize, size_t pCount) {
- const size_t cnt = std::min(pCount,(length-pos)/pSize),ofs = pSize*cnt;
-
- memcpy(pvBuffer,buffer+pos,ofs);
- pos += ofs;
-
- return cnt;
- }
-
- // -------------------------------------------------------------------
- // Write to stream
- size_t Write(const void* /* pvBuffer */, size_t /* pSize */,size_t /* pCount */) {
- ai_assert(false); // won't be needed
- return 0;
- }
-
- // -------------------------------------------------------------------
- // Seek specific position
- aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
- if (aiOrigin_SET == pOrigin) {
- if (pOffset >= length) {
- return AI_FAILURE;
- }
- pos = pOffset;
- }
- else if (aiOrigin_END == pOrigin) {
- if (pOffset >= length) {
- return AI_FAILURE;
- }
- pos = length-pOffset;
- }
- else {
- if (pOffset+pos >= length) {
- return AI_FAILURE;
- }
- pos += pOffset;
- }
- return AI_SUCCESS;
- }
-
- // -------------------------------------------------------------------
- // Get current seek position
- size_t Tell() const {
- return pos;
- }
-
- // -------------------------------------------------------------------
- // Get size of file
- size_t FileSize() const {
- return length;
- }
-
- // -------------------------------------------------------------------
- // Flush file contents
- void Flush() {
- ai_assert(false); // won't be needed
- }
-
-private:
- const uint8_t* buffer;
- size_t length,pos;
-};
-
-// ---------------------------------------------------------------------------
-/** Dummy IO system to read from a memory buffer */
-class MemoryIOSystem : public IOSystem
-{
-public:
- /** Constructor. */
- MemoryIOSystem (const uint8_t* buff, size_t len)
- : buffer (buff), length(len) {
- }
-
- /** Destructor. */
- ~MemoryIOSystem() {
- }
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const {
- return !strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH);
- }
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const {
- return '/'; // why not? it doesn't care
- }
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* /* pMode = "rb" */) {
- if (strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
- return NULL;
- }
- return new MemoryIOStream(buffer,length);
- }
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* /* pFile */) {
- }
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* /* one */, const char* /* second */) const {
- return false;
- }
-
-private:
- const uint8_t* buffer;
- size_t length;
-};
-} // end namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/NDOLoader.cpp b/3rdparty/assimp/code/NDOLoader.cpp
deleted file mode 100644
index c8dae587..00000000
--- a/3rdparty/assimp/code/NDOLoader.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2009, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file NDOLoader.cpp
- * Implementation of the NDO importer class.
- */
-
-#include "AssimpPCH.h"
-#ifndef AI_BUILD_NO_NDO_IMPORTER
-#include "NDOLoader.h"
-
-using namespace Assimp;
-#define for_each BOOST_FOREACH
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-NDOImporter::NDOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-NDOImporter::~NDOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if ( extension == "ndo")
- return true;
-
- if ((checkSig || !extension.length()) && pIOHandler) {
- const char* tokens[] = {"nendo"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-void NDOImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ndo");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void NDOImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void NDOImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
-
- // first 9 bytes are nendo file format ("nendo 1.n")
- const char* head = (const char*)reader.GetPtr();
- reader.IncPtr(9);
-
- if (strncmp("nendo ",head,6)) {
- throw DeadlyImportError("Not a Nendo file; magic signature missing");
- }
- // check if this is a supported version. if not, continue, too -- users,
- // please don't complain if it doesn't work then ...
- unsigned int file_format = 12;
- if (!strncmp("1.0",head+6,3)) {
- file_format = 10;
- DefaultLogger::get()->info("NDO file format is 1.0");
- }
- else if (!strncmp("1.1",head+6,3)) {
- file_format = 11;
- DefaultLogger::get()->info("NDO file format is 1.1");
- }
- else if (!strncmp("1.2",head+6,3)) {
- file_format = 12;
- DefaultLogger::get()->info("NDO file format is 1.2");
- }
- else {
- DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6));
- }
-
- reader.IncPtr(2); /* skip flags */
- if (file_format >= 12) {
- reader.IncPtr(2);
- }
- unsigned int temp = reader.GetU1();
-
- std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */
-
- // read all objects
- for (unsigned int o = 0; o < objects.size(); ++o) {
-
-// if (file_format < 12) {
- if (!reader.GetI1()) {
- continue; /* skip over empty object */
- }
- // reader.GetI2();
-// }
- Object& obj = objects[o];
-
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- head = (const char*)reader.GetPtr();
- reader.IncPtr(temp + 76); /* skip unknown stuff */
-
- obj.name = std::string(head, temp);
-
- // read edge table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.edges.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.edges.push_back(Edge());
- Edge& edge = obj.edges.back();
-
- for (unsigned int i = 0; i< 8; ++i) {
- edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
- edge.hard = file_format >= 11 ? reader.GetU1() : 0;
- for (unsigned int i = 0; i< 8; ++i) {
- edge.color[i] = reader.GetU1();
- }
- }
-
- // read face table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.faces.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.faces.push_back(Face());
- Face& face = obj.faces.back();
-
- face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- // read vertex table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.vertices.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.vertices.push_back(Vertex());
- Vertex& v = obj.vertices.back();
-
- v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- v.val.x = reader.GetF4();
- v.val.y = reader.GetF4();
- v.val.z = reader.GetF4();
- }
-
- // read UVs
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- for (unsigned int e = 0; e < temp; ++e) {
- file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- for (unsigned int e = 0; e < temp; ++e) {
- file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- if (reader.GetU1()) {
- const unsigned int x = reader.GetU2(), y = reader.GetU2();
- temp = 0;
- while (temp < x*y) {
- unsigned int repeat = reader.GetU1();
- reader.GetU1();
- reader.GetU1();
- reader.GetU1();
- temp += repeat;
- }
- }
- }
-
- // construct a dummy node graph and add all named objects as child nodes
- aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot");
- aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] ();
- pScene->mMeshes = new aiMesh* [ root->mNumChildren] ();
-
- std::vector<aiVector3D> vertices;
- std::vector<unsigned int> indices;
-
- for_each(const Object& obj,objects) {
- aiNode* nd = *cc++ = new aiNode(obj.name);
- nd->mParent = root;
-
- // translated from a python dict() - a vector might be sufficient as well
- typedef std::map<unsigned int, unsigned int> FaceTable;
- FaceTable face_table;
-
- unsigned int n = 0;
- for_each(const Edge& edge, obj.edges) {
-
- face_table[edge.edge[2]] = n;
- face_table[edge.edge[3]] = n;
-
- ++n;
- }
-
- aiMesh* mesh = new aiMesh();
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces=face_table.size()];
-
- vertices.clear();
- vertices.reserve(4 * face_table.size()); // arbitrarily choosen
- for_each(FaceTable::value_type& v, face_table) {
- indices.clear();
-
- aiFace& f = *faces++;
-
- const unsigned int key = v.first;
- unsigned int cur_edge = v.second;
- while (1) {
- unsigned int next_edge, next_vert;
- if (key == obj.edges[cur_edge].edge[3]) {
- next_edge = obj.edges[cur_edge].edge[5];
- next_vert = obj.edges[cur_edge].edge[1];
- }
- else {
- next_edge = obj.edges[cur_edge].edge[4];
- next_vert = obj.edges[cur_edge].edge[0];
- }
- indices.push_back( vertices.size() );
- vertices.push_back(obj.vertices[ next_vert ].val);
-
- cur_edge = next_edge;
- if (cur_edge == v.second) {
- break;
- }
- }
-
- f.mIndices = new unsigned int[f.mNumIndices = indices.size()];
- std::copy(indices.begin(),indices.end(),f.mIndices);
- }
-
- mesh->mVertices = new aiVector3D[mesh->mNumVertices = vertices.size()];
- std::copy(vertices.begin(),vertices.end(),mesh->mVertices);
-
- if (mesh->mNumVertices) {
- pScene->mMeshes[pScene->mNumMeshes] = mesh;
-
- (nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++;
- }
- }
-}
-
-#endif
diff --git a/3rdparty/assimp/code/NDOLoader.h b/3rdparty/assimp/code/NDOLoader.h
deleted file mode 100644
index 815b43c0..00000000
--- a/3rdparty/assimp/code/NDOLoader.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file NDOLoader.h
- * Declaration of the Nendo importer class.
- */
-#ifndef INCLUDED_AI_NDO_LOADER_H
-#define INCLUDED_AI_NDO_LOADER_H
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load meshes from Nendo.
- *
- * Basing on
- * <blender>/blender/release/scripts/nendo_import.py by Anthony D'Agostino.
-*/
-class NDOImporter : public BaseImporter
-{
- friend class Importer;
-protected:
- /** Constructor to be privately used by Importer */
- NDOImporter();
-
- /** Destructor, private as well */
- ~NDOImporter();
-
-public:
-
- //! Represents a single edge
- struct Edge
- {
- unsigned int edge[8];
- unsigned int hard;
- uint8_t color[8];
- };
-
- //! Represents a single face
- struct Face
- {
- unsigned int elem;
- };
-
- struct Vertex
- {
- unsigned int num;
- aiVector3D val;
- };
-
- //! Represents a single object
- struct Object
- {
- std::string name;
-
- std::vector<Edge> edges;
- std::vector<Face> faces;
- std::vector<Vertex> vertices;
- };
-
- // -------------------------------------------------------------------
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-}; // end of class NDOImporter
-} // end of namespace Assimp
-#endif // INCLUDED_AI_NDO_LOADER_H
diff --git a/3rdparty/assimp/code/NFFLoader.cpp b/3rdparty/assimp/code/NFFLoader.cpp
deleted file mode 100644
index 24a7b458..00000000
--- a/3rdparty/assimp/code/NFFLoader.cpp
+++ /dev/null
@@ -1,1256 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the STL importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-
-// internal headers
-#include "NFFLoader.h"
-#include "ParsingUtils.h"
-#include "StandardShapes.h"
-#include "fast_atof.h"
-#include "RemoveComments.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-NFFImporter::NFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-NFFImporter::~NFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool NFFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"nff","enff");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the list of all supported file extensions
-void NFFImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("enff");
- extensions.insert("nff");
-}
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_FLOAT(f) \
- SkipSpaces(&sz); \
- if (!::IsLineEnd(*sz))sz = fast_atof_move(sz, (float&)f);
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_TRIPLE(v) \
- AI_NFF_PARSE_FLOAT(v[0]) \
- AI_NFF_PARSE_FLOAT(v[1]) \
- AI_NFF_PARSE_FLOAT(v[2])
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_SHAPE_INFORMATION() \
- aiVector3D center, radius(1.0f,get_qnan(),get_qnan()); \
- AI_NFF_PARSE_TRIPLE(center); \
- AI_NFF_PARSE_TRIPLE(radius); \
- if (is_qnan(radius.z))radius.z = radius.x; \
- if (is_qnan(radius.y))radius.y = radius.x; \
- currentMesh.radius = radius; \
- currentMesh.center = center;
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF2_GET_NEXT_TOKEN() \
- do \
- { \
- if (!GetNextLine(buffer,line)) \
- {DefaultLogger::get()->warn("NFF2: Unexpected EOF, can't read next token");break;} \
- SkipSpaces(line,&sz); \
- } \
- while (IsLineEnd(*sz))
-
-
-// ------------------------------------------------------------------------------------------------
-// Loads the materail table for the NFF2 file format from an external file
-void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
- const std::string& path, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( path, "rb"));
-
- // Check whether we can read from the file
- if ( !file.get()) {
- DefaultLogger::get()->error("NFF2: Unable to open material library " + path + ".");
- return;
- }
-
- // get the size of the file
- const unsigned int m = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2(m+1);
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // First of all: remove all comments from the file
- CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
-
- // The file should start with the magic sequence "mat"
- if (!TokenMatch(buffer,"mat",3)) {
- DefaultLogger::get()->error("NFF2: Not a valid material library " + path + ".");
- return;
- }
-
- ShadingInfo* curShader = NULL;
-
- // No read the file line per line
- char line[4096];
- const char* sz;
- while (GetNextLine(buffer,line))
- {
- SkipSpaces(line,&sz);
-
- // 'version' defines the version of the file format
- if (TokenMatch(sz,"version",7))
- {
- DefaultLogger::get()->info("NFF (Sense8) material library file format: " + std::string(sz));
- }
- // 'matdef' starts a new material in the file
- else if (TokenMatch(sz,"matdef",6))
- {
- // add a new material to the list
- output.push_back( ShadingInfo() );
- curShader = & output.back();
-
- // parse the name of the material
- }
- else if (!TokenMatch(sz,"valid",5))
- {
- // check whether we have an active material at the moment
- if (!IsLineEnd(*sz))
- {
- if (!curShader)
- {
- DefaultLogger::get()->error(std::string("NFF2 material library: Found element ") +
- sz + "but there is no active material");
- continue;
- }
- }
- else continue;
-
- // now read the material property and determine its type
- aiColor3D c;
- if (TokenMatch(sz,"ambient",7))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->ambient = c;
- }
- else if (TokenMatch(sz,"diffuse",7) || TokenMatch(sz,"ambientdiffuse",14) /* correct? */)
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->diffuse = curShader->ambient = c;
- }
- else if (TokenMatch(sz,"specular",8))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->specular = c;
- }
- else if (TokenMatch(sz,"emission",8))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->emissive = c;
- }
- else if (TokenMatch(sz,"shininess",9))
- {
- AI_NFF_PARSE_FLOAT(curShader->shininess);
- }
- else if (TokenMatch(sz,"opacity",7))
- {
- AI_NFF_PARSE_FLOAT(curShader->opacity);
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void NFFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( !file.get())
- throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
-
- unsigned int m = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // mesh arrays - separate here to make the handling of the pointers below easier.
- std::vector<MeshInfo> meshes;
- std::vector<MeshInfo> meshesWithNormals;
- std::vector<MeshInfo> meshesWithUVCoords;
- std::vector<MeshInfo> meshesLocked;
-
- char line[4096];
- const char* sz;
-
- // camera parameters
- aiVector3D camPos, camUp(0.f,1.f,0.f), camLookAt(0.f,0.f,1.f);
- float angle = 45.f;
- aiVector2D resolution;
-
- bool hasCam = false;
-
- MeshInfo* currentMeshWithNormals = NULL;
- MeshInfo* currentMesh = NULL;
- MeshInfo* currentMeshWithUVCoords = NULL;
-
- ShadingInfo s; // current material info
-
- // degree of tesselation
- unsigned int iTesselation = 4;
-
- // some temporary variables we need to parse the file
- unsigned int sphere = 0,
- cylinder = 0,
- cone = 0,
- numNamed = 0,
- dodecahedron = 0,
- octahedron = 0,
- tetrahedron = 0,
- hexahedron = 0;
-
- // lights imported from the file
- std::vector<Light> lights;
-
- // check whether this is the NFF2 file format
- if (TokenMatch(buffer,"nff",3))
- {
- const float qnan = get_qnan();
- const aiColor4D cQNAN = aiColor4D (qnan,0.f,0.f,1.f);
- const aiVector3D vQNAN = aiVector3D(qnan,0.f,0.f);
-
- // another NFF file format ... just a raw parser has been implemented
- // no support for further details, I don't think it is worth the effort
- // http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/nff/nff2.html
- // http://www.netghost.narod.ru/gff/graphics/summary/sense8.htm
-
- // First of all: remove all comments from the file
- CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
-
- while (GetNextLine(buffer,line))
- {
- SkipSpaces(line,&sz);
- if (TokenMatch(sz,"version",7))
- {
- DefaultLogger::get()->info("NFF (Sense8) file format: " + std::string(sz));
- }
- else if (TokenMatch(sz,"viewpos",7))
- {
- AI_NFF_PARSE_TRIPLE(camPos);
- hasCam = true;
- }
- else if (TokenMatch(sz,"viewdir",7))
- {
- AI_NFF_PARSE_TRIPLE(camLookAt);
- hasCam = true;
- }
- // This starts a new object section
- else if (!IsSpaceOrNewLine(*sz))
- {
- unsigned int subMeshIdx = 0;
-
- // read the name of the object, skip all spaces
- // at the end of it.
- const char* sz3 = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- std::string objectName = std::string(sz3,(unsigned int)(sz-sz3));
-
- const unsigned int objStart = (unsigned int)meshes.size();
-
- // There could be a material table in a separate file
- std::vector<ShadingInfo> materialTable;
- while (true)
- {
- AI_NFF2_GET_NEXT_TOKEN();
-
- // material table - an external file
- if (TokenMatch(sz,"mtable",6))
- {
- SkipSpaces(&sz);
- sz3 = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- const unsigned int diff = (unsigned int)(sz-sz3);
- if (!diff)DefaultLogger::get()->warn("NFF2: Found empty mtable token");
- else
- {
- // The material table has the file extension .mat.
- // If it is not there, we need to append it
- std::string path = std::string(sz3,diff);
- if (std::string::npos == path.find_last_of(".mat"))
- {
- path.append(".mat");
- }
-
- // Now extract the working directory from the path to
- // this file and append the material library filename
- // to it.
- std::string::size_type s;
- if ((std::string::npos == (s = path.find_last_of('\\')) || !s) &&
- (std::string::npos == (s = path.find_last_of('/')) || !s) )
- {
- s = pFile.find_last_of('\\');
- if (std::string::npos == s)s = pFile.find_last_of('/');
- if (std::string::npos != s)
- {
- path = pFile.substr(0,s+1) + path;
- }
- }
- LoadNFF2MaterialTable(materialTable,path,pIOHandler);
- }
- }
- else break;
- }
-
- // read the numbr of vertices
- unsigned int num = ::strtol10(sz,&sz);
-
- // temporary storage
- std::vector<aiColor4D> tempColors;
- std::vector<aiVector3D> tempPositions,tempTextureCoords,tempNormals;
-
- bool hasNormals = false,hasUVs = false,hasColor = false;
-
- tempPositions.reserve (num);
- tempColors.reserve (num);
- tempNormals.reserve (num);
- tempTextureCoords.reserve (num);
- for (unsigned int i = 0; i < num; ++i)
- {
- AI_NFF2_GET_NEXT_TOKEN();
- aiVector3D v;
- AI_NFF_PARSE_TRIPLE(v);
- tempPositions.push_back(v);
-
- // parse all other attributes in the line
- while (true)
- {
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))break;
-
- // color definition
- if (TokenMatch(sz,"0x",2))
- {
- hasColor = true;
- register unsigned int numIdx = ::strtol16(sz,&sz);
- aiColor4D clr;
- clr.a = 1.f;
-
- // 0xRRGGBB
- clr.r = ((numIdx >> 16u) & 0xff) / 255.f;
- clr.g = ((numIdx >> 8u) & 0xff) / 255.f;
- clr.b = ((numIdx) & 0xff) / 255.f;
- tempColors.push_back(clr);
- }
- // normal vector
- else if (TokenMatch(sz,"norm",4))
- {
- hasNormals = true;
- AI_NFF_PARSE_TRIPLE(v);
- tempNormals.push_back(v);
- }
- // UV coordinate
- else if (TokenMatch(sz,"uv",2))
- {
- hasUVs = true;
- AI_NFF_PARSE_FLOAT(v.x);
- AI_NFF_PARSE_FLOAT(v.y);
- v.z = 0.f;
- tempTextureCoords.push_back(v);
- }
- }
-
- // fill in dummies for all attributes that have not been set
- if (tempNormals.size() != tempPositions.size())
- tempNormals.push_back(vQNAN);
-
- if (tempTextureCoords.size() != tempPositions.size())
- tempTextureCoords.push_back(vQNAN);
-
- if (tempColors.size() != tempPositions.size())
- tempColors.push_back(cQNAN);
- }
-
- AI_NFF2_GET_NEXT_TOKEN();
- if (!num)throw DeadlyImportError("NFF2: There are zero vertices");
- num = ::strtol10(sz,&sz);
-
- std::vector<unsigned int> tempIdx;
- tempIdx.reserve(10);
- for (unsigned int i = 0; i < num; ++i)
- {
- AI_NFF2_GET_NEXT_TOKEN();
- SkipSpaces(line,&sz);
- unsigned int numIdx = ::strtol10(sz,&sz);
-
- // read all faces indices
- if (numIdx)
- {
- // mesh.faces.push_back(numIdx);
- // tempIdx.erase(tempIdx.begin(),tempIdx.end());
- tempIdx.resize(numIdx);
-
- for (unsigned int a = 0; a < numIdx;++a)
- {
- SkipSpaces(sz,&sz);
- m = ::strtol10(sz,&sz);
- if (m >= (unsigned int)tempPositions.size())
- {
- DefaultLogger::get()->error("NFF2: Vertex index overflow");
- m= 0;
- }
- // mesh.vertices.push_back (tempPositions[idx]);
- tempIdx[a] = m;
- }
- }
-
- // build a temporary shader object for the face.
- ShadingInfo shader;
- unsigned int matIdx = 0;
-
- // white material color - we have vertex colors
- shader.color = aiColor3D(1.f,1.f,1.f);
- aiColor4D c = aiColor4D(1.f,1.f,1.f,1.f);
- while (true)
- {
- SkipSpaces(sz,&sz);
- if (IsLineEnd(*sz))break;
-
- // per-polygon colors
- if (TokenMatch(sz,"0x",2))
- {
- hasColor = true;
- const char* sz2 = sz;
- numIdx = ::strtol16(sz,&sz);
- const unsigned int diff = (unsigned int)(sz-sz2);
-
- // 0xRRGGBB
- if (diff > 3)
- {
- c.r = ((numIdx >> 16u) & 0xff) / 255.f;
- c.g = ((numIdx >> 8u) & 0xff) / 255.f;
- c.b = ((numIdx) & 0xff) / 255.f;
- }
- // 0xRGB
- else
- {
- c.r = ((numIdx >> 8u) & 0xf) / 16.f;
- c.g = ((numIdx >> 4u) & 0xf) / 16.f;
- c.b = ((numIdx) & 0xf) / 16.f;
- }
- }
- // TODO - implement texture mapping here
-#if 0
- // mirror vertex texture coordinate?
- else if (TokenMatch(sz,"mirror",6))
- {
- }
- // texture coordinate scaling
- else if (TokenMatch(sz,"scale",5))
- {
- }
- // texture coordinate translation
- else if (TokenMatch(sz,"trans",5))
- {
- }
- // texture coordinate rotation angle
- else if (TokenMatch(sz,"rot",3))
- {
- }
-#endif
-
- // texture file name for this polygon + mapping information
- else if ('_' == sz[0])
- {
- // get mapping information
- switch (sz[1])
- {
- case 'v':
- case 'V':
-
- shader.shaded = false;
- break;
-
- case 't':
- case 'T':
- case 'u':
- case 'U':
-
- DefaultLogger::get()->warn("Unsupported NFF2 texture attribute: trans");
- };
- if (!sz[1] || '_' != sz[2])
- {
- DefaultLogger::get()->warn("NFF2: Expected underscore after texture attributes");
- continue;
- }
- const char* sz2 = sz+3;
- while (!IsSpaceOrNewLine( *sz ))++sz;
- const unsigned int diff = (unsigned int)(sz-sz2);
- if (diff)shader.texFile = std::string(sz2,diff);
- }
-
- // Two-sided material?
- else if (TokenMatch(sz,"both",4))
- {
- shader.twoSided = true;
- }
-
- // Material ID?
- else if (!materialTable.empty() && TokenMatch(sz,"matid",5))
- {
- SkipSpaces(&sz);
- matIdx = ::strtol10(sz,&sz);
- if (matIdx >= materialTable.size())
- {
- DefaultLogger::get()->error("NFF2: Material index overflow.");
- matIdx = 0;
- }
-
- // now combine our current shader with the shader we
- // read from the material table.
- ShadingInfo& mat = materialTable[matIdx];
- shader.ambient = mat.ambient;
- shader.diffuse = mat.diffuse;
- shader.emissive = mat.emissive;
- shader.opacity = mat.opacity;
- shader.specular = mat.specular;
- shader.shininess = mat.shininess;
- }
- else SkipToken(sz);
- }
-
- // search the list of all shaders we have for this object whether
- // there is an identical one. In this case, we append our mesh
- // data to it.
- MeshInfo* mesh = NULL;
- for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
- it != end; ++it)
- {
- if ((*it).shader == shader && (*it).matIndex == matIdx)
- {
- // we have one, we can append our data to it
- mesh = &(*it);
- }
- }
- if (!mesh)
- {
- meshes.push_back(MeshInfo(PatchType_Simple,false));
- mesh = &meshes.back();
- mesh->matIndex = matIdx;
-
- // We need to add a new mesh to the list. We assign
- // an unique name to it to make sure the scene will
- // pass the validation step for the moment.
- // TODO: fix naming of objects in the scenegraph later
- if (objectName.length())
- {
- ::strcpy(mesh->name,objectName.c_str());
- ASSIMP_itoa10(&mesh->name[objectName.length()],30,subMeshIdx++);
- }
-
- // copy the shader to the mesh.
- mesh->shader = shader;
- }
-
- // fill the mesh with data
- if (!tempIdx.empty())
- {
- mesh->faces.push_back((unsigned int)tempIdx.size());
- for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
- it != end;++it)
- {
- m = *it;
-
- // copy colors -vertex color specifications override polygon color specifications
- if (hasColor)
- {
- const aiColor4D& clr = tempColors[m];
- mesh->colors.push_back((is_qnan( clr.r ) ? c : clr));
- }
-
- // positions should always be there
- mesh->vertices.push_back (tempPositions[m]);
-
- // copy normal vectors
- if (hasNormals)
- mesh->normals.push_back (tempNormals[m]);
-
- // copy texture coordinates
- if (hasUVs)
- mesh->uvs.push_back (tempTextureCoords[m]);
- }
- }
- }
- if (!num)throw DeadlyImportError("NFF2: There are zero faces");
- }
- }
- camLookAt = camLookAt + camPos;
- }
- else // "Normal" Neutral file format that is quite more common
- {
- while (GetNextLine(buffer,line))
- {
- sz = line;
- if ('p' == line[0] || TokenMatch(sz,"tpp",3))
- {
- MeshInfo* out = NULL;
-
- // 'tpp' - texture polygon patch primitive
- if ('t' == line[0])
- {
- currentMeshWithUVCoords = NULL;
- for (std::vector<MeshInfo>::iterator it = meshesWithUVCoords.begin(), end = meshesWithUVCoords.end();
- it != end;++it)
- {
- if ((*it).shader == s)
- {
- currentMeshWithUVCoords = &(*it);
- break;
- }
- }
-
- if (!currentMeshWithUVCoords)
- {
- meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
- currentMeshWithUVCoords = &meshesWithUVCoords.back();
- currentMeshWithUVCoords->shader = s;
- }
- out = currentMeshWithUVCoords;
- }
- // 'pp' - polygon patch primitive
- else if ('p' == line[1])
- {
- currentMeshWithNormals = NULL;
- for (std::vector<MeshInfo>::iterator it = meshesWithNormals.begin(), end = meshesWithNormals.end();
- it != end;++it)
- {
- if ((*it).shader == s)
- {
- currentMeshWithNormals = &(*it);
- break;
- }
- }
-
- if (!currentMeshWithNormals)
- {
- meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
- currentMeshWithNormals = &meshesWithNormals.back();
- currentMeshWithNormals->shader = s;
- }
- sz = &line[2];out = currentMeshWithNormals;
- }
- // 'p' - polygon primitive
- else
- {
- currentMesh = NULL;
- for (std::vector<MeshInfo>::iterator it = meshes.begin(), end = meshes.end();
- it != end;++it)
- {
- if ((*it).shader == s)
- {
- currentMesh = &(*it);
- break;
- }
- }
-
- if (!currentMesh)
- {
- meshes.push_back(MeshInfo(PatchType_Simple));
- currentMesh = &meshes.back();
- currentMesh->shader = s;
- }
- sz = &line[1];out = currentMesh;
- }
- SkipSpaces(sz,&sz);
- m = strtol10(sz);
-
- // ---- flip the face order
- out->vertices.resize(out->vertices.size()+m);
- if (out != currentMesh)
- {
- out->normals.resize(out->vertices.size());
- }
- if (out == currentMeshWithUVCoords)
- {
- out->uvs.resize(out->vertices.size());
- }
- for (unsigned int n = 0; n < m;++n)
- {
- if (!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected EOF was encountered. Patch definition incomplete");
- continue;
- }
-
- aiVector3D v; sz = &line[0];
- AI_NFF_PARSE_TRIPLE(v);
- out->vertices[out->vertices.size()-n-1] = v;
-
- if (out != currentMesh)
- {
- AI_NFF_PARSE_TRIPLE(v);
- out->normals[out->vertices.size()-n-1] = v;
- }
- if (out == currentMeshWithUVCoords)
- {
- // FIX: in one test file this wraps over multiple lines
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))
- {
- GetNextLine(buffer,line);
- sz = line;
- }
- AI_NFF_PARSE_FLOAT(v.x);
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))
- {
- GetNextLine(buffer,line);
- sz = line;
- }
- AI_NFF_PARSE_FLOAT(v.y);
- v.y = 1.f - v.y;
- out->uvs[out->vertices.size()-n-1] = v;
- }
- }
- out->faces.push_back(m);
- }
- // 'f' - shading information block
- else if (TokenMatch(sz,"f",1))
- {
- float d;
-
- // read the RGB colors
- AI_NFF_PARSE_TRIPLE(s.color);
-
- // read the other properties
- AI_NFF_PARSE_FLOAT(s.diffuse.r);
- AI_NFF_PARSE_FLOAT(s.specular.r);
- AI_NFF_PARSE_FLOAT(d); // skip shininess and transmittance
- AI_NFF_PARSE_FLOAT(d);
- AI_NFF_PARSE_FLOAT(s.refracti);
-
- // NFF2 uses full colors here so we need to use them too
- // although NFF uses simple scaling factors
- s.diffuse.g = s.diffuse.b = s.diffuse.r;
- s.specular.g = s.specular.b = s.specular.r;
-
- // if the next one is NOT a number we assume it is a texture file name
- // this feature is used by some NFF files on the internet and it has
- // been implemented as it can be really useful
- SkipSpaces(&sz);
- if (!IsNumeric(*sz))
- {
- // TODO: Support full file names with spaces and quotation marks ...
- const char* p = sz;
- while (!IsSpaceOrNewLine( *sz ))++sz;
-
- unsigned int diff = (unsigned int)(sz-p);
- if (diff)
- {
- s.texFile = std::string(p,diff);
- }
- }
- else
- {
- AI_NFF_PARSE_FLOAT(s.ambient); // optional
- }
- }
- // 'shader' - other way to specify a texture
- else if (TokenMatch(sz,"shader",6))
- {
- SkipSpaces(&sz);
- const char* old = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- s.texFile = std::string(old, (uintptr_t)sz - (uintptr_t)old);
- }
- // 'l' - light source
- else if (TokenMatch(sz,"l",1))
- {
- lights.push_back(Light());
- Light& light = lights.back();
-
- AI_NFF_PARSE_TRIPLE(light.position);
- AI_NFF_PARSE_FLOAT (light.intensity);
- AI_NFF_PARSE_TRIPLE(light.color);
- }
- // 's' - sphere
- else if (TokenMatch(sz,"s",1))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeSphere(iTesselation, currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::sprintf(currentMesh.name,"sphere_%i",sphere++);
- }
- // 'dod' - dodecahedron
- else if (TokenMatch(sz,"dod",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeDodecahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::sprintf(currentMesh.name,"dodecahedron_%i",dodecahedron++);
- }
-
- // 'oct' - octahedron
- else if (TokenMatch(sz,"oct",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeOctahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::sprintf(currentMesh.name,"octahedron_%i",octahedron++);
- }
-
- // 'tet' - tetrahedron
- else if (TokenMatch(sz,"tet",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeTetrahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::sprintf(currentMesh.name,"tetrahedron_%i",tetrahedron++);
- }
-
- // 'hex' - hexahedron
- else if (TokenMatch(sz,"hex",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_BOX;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeHexahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::sprintf(currentMesh.name,"hexahedron_%i",hexahedron++);
- }
- // 'c' - cone
- else if (TokenMatch(sz,"c",1))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_CYLINDER;
-
- if (!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
- break;
- }
- sz = line;
-
- // read the two center points and the respective radii
- aiVector3D center1, center2; float radius1, radius2;
- AI_NFF_PARSE_TRIPLE(center1);
- AI_NFF_PARSE_FLOAT(radius1);
-
- if (!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
- break;
- }
- sz = line;
-
- AI_NFF_PARSE_TRIPLE(center2);
- AI_NFF_PARSE_FLOAT(radius2);
-
- // compute the center point of the cone/cylinder -
- // it is its local transformation origin
- currentMesh.dir = center2-center1;
- currentMesh.center = center1+currentMesh.dir/2.f;
-
- float f;
- if (( f = currentMesh.dir.Length()) < 10e-3f )
- {
- DefaultLogger::get()->error("NFF: Cone height is close to zero");
- continue;
- }
- currentMesh.dir /= f; // normalize
-
- // generate the cone - it consists of simple triangles
- StandardShapes::MakeCone(f, radius1, radius2,
- integer_pow(4, iTesselation), currentMesh.vertices);
-
- // MakeCone() returns tris
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh. 'cone' if it a cone,
- // 'cylinder' if it is a cylinder. Funny, isn't it?
- if (radius1 != radius2)
- ::sprintf(currentMesh.name,"cone_%i",cone++);
- else ::sprintf(currentMesh.name,"cylinder_%i",cylinder++);
- }
- // 'tess' - tesselation
- else if (TokenMatch(sz,"tess",4))
- {
- SkipSpaces(&sz);
- iTesselation = strtol10(sz);
- }
- // 'from' - camera position
- else if (TokenMatch(sz,"from",4))
- {
- AI_NFF_PARSE_TRIPLE(camPos);
- hasCam = true;
- }
- // 'at' - camera look-at vector
- else if (TokenMatch(sz,"at",2))
- {
- AI_NFF_PARSE_TRIPLE(camLookAt);
- hasCam = true;
- }
- // 'up' - camera up vector
- else if (TokenMatch(sz,"up",2))
- {
- AI_NFF_PARSE_TRIPLE(camUp);
- hasCam = true;
- }
- // 'angle' - (half?) camera field of view
- else if (TokenMatch(sz,"angle",5))
- {
- AI_NFF_PARSE_FLOAT(angle);
- hasCam = true;
- }
- // 'resolution' - used to compute the screen aspect
- else if (TokenMatch(sz,"resolution",10))
- {
- AI_NFF_PARSE_FLOAT(resolution.x);
- AI_NFF_PARSE_FLOAT(resolution.y);
- hasCam = true;
- }
- // 'pb' - bezier patch. Not supported yet
- else if (TokenMatch(sz,"pb",2))
- {
- DefaultLogger::get()->error("NFF: Encountered unsupported ID: bezier patch");
- }
- // 'pn' - NURBS. Not supported yet
- else if (TokenMatch(sz,"pn",2) || TokenMatch(sz,"pnn",3))
- {
- DefaultLogger::get()->error("NFF: Encountered unsupported ID: NURBS");
- }
- // '' - comment
- else if ('#' == line[0])
- {
- const char* sz;SkipSpaces(&line[1],&sz);
- if (!IsLineEnd(*sz))DefaultLogger::get()->info(sz);
- }
- }
- }
-
- // copy all arrays into one large
- meshes.reserve (meshes.size()+meshesLocked.size()+meshesWithNormals.size()+meshesWithUVCoords.size());
- meshes.insert (meshes.end(),meshesLocked.begin(),meshesLocked.end());
- meshes.insert (meshes.end(),meshesWithNormals.begin(),meshesWithNormals.end());
- meshes.insert (meshes.end(),meshesWithUVCoords.begin(),meshesWithUVCoords.end());
-
- // now generate output meshes. first find out how many meshes we'll need
- std::vector<MeshInfo>::const_iterator it = meshes.begin(), end = meshes.end();
- for (;it != end;++it)
- {
- if (!(*it).faces.empty())
- {
- ++pScene->mNumMeshes;
- if ((*it).name[0])++numNamed;
- }
- }
-
- // generate a dummy root node - assign all unnamed elements such
- // as polygons and polygon patches to the root node and generate
- // sub nodes for named objects such as spheres and cones.
- aiNode* const root = new aiNode();
- root->mName.Set("<NFF_Root>");
- root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int) lights.size();
- root->mNumMeshes = pScene->mNumMeshes-numNamed;
-
- aiNode** ppcChildren = NULL;
- unsigned int* pMeshes = NULL;
- if (root->mNumMeshes)
- pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
- if (root->mNumChildren)
- ppcChildren = root->mChildren = new aiNode*[root->mNumChildren];
-
- // generate the camera
- if (hasCam)
- {
- aiNode* nd = *ppcChildren = new aiNode();
- nd->mName.Set("<NFF_Camera>");
- nd->mParent = root;
-
- // allocate the camera in the scene
- pScene->mNumCameras = 1;
- pScene->mCameras = new aiCamera*[1];
- aiCamera* c = pScene->mCameras[0] = new aiCamera;
-
- c->mName = nd->mName; // make sure the names are identical
- c->mHorizontalFOV = AI_DEG_TO_RAD( angle );
- c->mLookAt = camLookAt - camPos;
- c->mPosition = camPos;
- c->mUp = camUp;
-
- // If the resolution is not specified in the file, we
- // need to set 1.0 as aspect.
- c->mAspect = (!resolution.y ? 0.f : resolution.x / resolution.y);
- ++ppcChildren;
- }
-
- // generate light sources
- if (!lights.empty())
- {
- pScene->mNumLights = (unsigned int)lights.size();
- pScene->mLights = new aiLight*[pScene->mNumLights];
- for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
- {
- const Light& l = lights[i];
-
- aiNode* nd = *ppcChildren = new aiNode();
- nd->mParent = root;
-
- nd->mName.length = ::sprintf(nd->mName.data,"<NFF_Light%i>",i);
-
- // allocate the light in the scene data structure
- aiLight* out = pScene->mLights[i] = new aiLight();
- out->mName = nd->mName; // make sure the names are identical
- out->mType = aiLightSource_POINT;
- out->mColorDiffuse = out->mColorSpecular = l.color * l.intensity;
- out->mPosition = l.position;
- }
- }
-
- if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
- for (it = meshes.begin(), m = 0; it != end;++it)
- {
- if ((*it).faces.empty())continue;
-
- const MeshInfo& src = *it;
- aiMesh* const mesh = pScene->mMeshes[m] = new aiMesh();
- mesh->mNumVertices = (unsigned int)src.vertices.size();
- mesh->mNumFaces = (unsigned int)src.faces.size();
-
- // Generate sub nodes for named meshes
- if (src.name[0])
- {
- aiNode* const node = *ppcChildren = new aiNode();
- node->mParent = root;
- node->mNumMeshes = 1;
- node->mMeshes = new unsigned int[1];
- node->mMeshes[0] = m;
- node->mName.Set(src.name);
-
- // setup the transformation matrix of the node
- aiMatrix4x4::FromToMatrix(aiVector3D(0.f,1.f,0.f),
- src.dir,node->mTransformation);
-
- aiMatrix4x4& mat = node->mTransformation;
- mat.a1 *= src.radius.x; mat.b1 *= src.radius.x; mat.c1 *= src.radius.x;
- mat.a2 *= src.radius.y; mat.b2 *= src.radius.y; mat.c2 *= src.radius.y;
- mat.a3 *= src.radius.z; mat.b3 *= src.radius.z; mat.c3 *= src.radius.z;
- mat.a4 = src.center.x;
- mat.b4 = src.center.y;
- mat.c4 = src.center.z;
-
- ++ppcChildren;
- }
- else *pMeshes++ = m;
-
- // copy vertex positions
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mVertices,&src.vertices[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
-
- // NFF2: there could be vertex colors
- if (!src.colors.empty())
- {
- ai_assert(src.colors.size() == src.vertices.size());
-
- // copy vertex colors
- mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
- ::memcpy(mesh->mColors[0],&src.colors[0],
- sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- if (!src.normals.empty())
- {
- ai_assert(src.normals.size() == src.vertices.size());
-
- // copy normal vectors
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mNormals,&src.normals[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
- }
-
- if (!src.uvs.empty())
- {
- ai_assert(src.uvs.size() == src.vertices.size());
-
- // copy texture coordinates
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mTextureCoords[0],&src.uvs[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
- }
-
- // generate faces
- unsigned int p = 0;
- aiFace* pFace = mesh->mFaces = new aiFace[mesh->mNumFaces];
- for (std::vector<unsigned int>::const_iterator it2 = src.faces.begin(),
- end2 = src.faces.end();
- it2 != end2;++it2,++pFace)
- {
- pFace->mIndices = new unsigned int [ pFace->mNumIndices = *it2 ];
- for (unsigned int o = 0; o < pFace->mNumIndices;++o)
- pFace->mIndices[o] = p++;
- }
-
- // generate a material for the mesh
- MaterialHelper* pcMat = (MaterialHelper*)(pScene->mMaterials[m] = new MaterialHelper());
-
- mesh->mMaterialIndex = m++;
-
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- pcMat->AddProperty(&s, AI_MATKEY_NAME);
-
- // FIX: Ignore diffuse == 0
- aiColor3D c = src.shader.color * (src.shader.diffuse.r ? src.shader.diffuse : aiColor3D(1.f,1.f,1.f));
- pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
- c = src.shader.color * src.shader.specular;
- pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
-
- // NFF2 - default values for NFF
- pcMat->AddProperty(&src.shader.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
- pcMat->AddProperty(&src.shader.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
- pcMat->AddProperty(&src.shader.opacity, 1,AI_MATKEY_OPACITY);
-
- // setup the first texture layer, if existing
- if (src.shader.texFile.length())
- {
- s.Set(src.shader.texFile);
- pcMat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- if (aiTextureMapping_UV != src.shader.mapping) {
-
- aiVector3D v(0.f,-1.f,0.f);
- pcMat->AddProperty(&v, 1,AI_MATKEY_TEXMAP_AXIS_DIFFUSE(0));
- pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0));
- }
- }
-
- // setup the name of the material
- if (src.shader.name.length())
- {
- s.Set(src.shader.texFile);
- pcMat->AddProperty(&s,AI_MATKEY_NAME);
- }
-
- // setup some more material properties that are specific to NFF2
- int i;
- if (src.shader.twoSided)
- {
- i = 1;
- pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
- }
- i = (src.shader.shaded ? aiShadingMode_Gouraud : aiShadingMode_NoShading);
- if (src.shader.shininess)
- {
- i = aiShadingMode_Phong;
- pcMat->AddProperty(&src.shader.shininess,1,AI_MATKEY_SHININESS);
- }
- pcMat->AddProperty(&i,1,AI_MATKEY_SHADING_MODEL);
- }
- pScene->mRootNode = root;
-}
-
-#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER
diff --git a/3rdparty/assimp/code/NFFLoader.h b/3rdparty/assimp/code/NFFLoader.h
deleted file mode 100644
index 464792ca..00000000
--- a/3rdparty/assimp/code/NFFLoader.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file NFFLoader.h
- * @brief Declaration of the NFF importer class.
- */
-#ifndef AI_NFFLOADER_H_INCLUDED
-#define AI_NFFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <vector>
-
-#include "../include/aiTypes.h"
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** NFF (Neutral File Format) Importer class.
- *
- * The class implements both Eric Haynes NFF format and Sense8's NFF (NFF2) format.
- * Both are quite different and the loading code is somewhat dirty at
- * the moment. Sense8 should be moved to a separate loader.
-*/
-class NFFImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- NFFImporter();
-
- /** Destructor, private as well */
- ~NFFImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-
- // describes face material properties
- struct ShadingInfo
- {
- ShadingInfo()
- : color (0.6f,0.6f,0.6f)
- , diffuse (1.f,1.f,1.f)
- , specular (1.f,1.f,1.f)
- , ambient (0.f,0.f,0.f)
- , emissive (0.f,0.f,0.f)
- , refracti (1.f)
- , twoSided (false) // for NFF2
- , shaded (true) // for NFF2
- , opacity (1.f)
- , shininess (0.f)
- , mapping (aiTextureMapping_UV)
- {}
-
- aiColor3D color,diffuse,specular,ambient,emissive;
- float refracti;
-
- std::string texFile;
-
- // For NFF2
- bool twoSided;
- bool shaded;
- float opacity, shininess;
-
- std::string name;
-
- // texture mapping to be generated for the mesh - uv is the default
- // it means: use UV if there, nothing otherwise. This property is
- // used for locked meshes.
- aiTextureMapping mapping;
-
- // shininess is ignored for the moment
- bool operator == (const ShadingInfo& other) const
- {
- return color == other.color &&
- diffuse == other.diffuse &&
- specular == other.specular &&
- ambient == other.ambient &&
- refracti == other.refracti &&
- texFile == other.texFile &&
- twoSided == other.twoSided &&
- shaded == other.shaded;
-
- // Some properties from NFF2 aren't compared by this operator.
- // Comparing MeshInfo::matIndex should do that.
- }
- };
-
- // describes a NFF light source
- struct Light
- {
- Light()
- : intensity (1.f)
- , color (1.f,1.f,1.f)
- {}
-
- aiVector3D position;
- float intensity;
- aiColor3D color;
- };
-
- enum PatchType
- {
- PatchType_Simple = 0x0,
- PatchType_Normals = 0x1,
- PatchType_UVAndNormals = 0x2
- };
-
- // describes a NFF mesh
- struct MeshInfo
- {
- MeshInfo(PatchType _pType, bool bL = false)
- : pType (_pType)
- , bLocked (bL)
- , radius (1.f,1.f,1.f)
- , dir (0.f,1.f,0.f)
- , matIndex (0)
- {
- name[0] = '\0'; // by default meshes are unnamed
- }
-
- ShadingInfo shader;
- PatchType pType;
- bool bLocked;
-
- // for spheres, cones and cylinders: center point of the object
- aiVector3D center, radius, dir;
-
- char name[128];
-
- std::vector<aiVector3D> vertices, normals, uvs;
- std::vector<unsigned int> faces;
-
- // for NFF2
- std::vector<aiColor4D> colors;
- unsigned int matIndex;
- };
-
-
- // -------------------------------------------------------------------
- /** Loads the material table for the NFF2 file format from an
- * external file.
- *
- * @param output Receives the list of output meshes
- * @param path Path to the file (abs. or rel.)
- * @param pIOHandler IOSystem to be used to open the file
- */
- void LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
- const std::string& path, IOSystem* pIOHandler);
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_NFFIMPORTER_H_IN
diff --git a/3rdparty/assimp/code/OFFLoader.cpp b/3rdparty/assimp/code/OFFLoader.cpp
deleted file mode 100644
index 38e21b49..00000000
--- a/3rdparty/assimp/code/OFFLoader.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file OFFLoader.cpp
- * @brief Implementation of the OFF importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-
-// internal headers
-#include "OFFLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OFFImporter::OFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OFFImporter::~OFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "off")
- return true;
- else if (!extension.length() || checkSig)
- {
- if (!pIOHandler)return true;
- const char* tokens[] = {"off"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void OFFImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("off");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void OFFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- char line[4096];
- GetNextLine(buffer,line);
- if ('O' == line[0]) {
- GetNextLine(buffer,line); // skip the 'OFF' line
- }
-
- const char* sz = line; SkipSpaces(&sz);
- const unsigned int numVertices = strtol10(sz,&sz);SkipSpaces(&sz);
- const unsigned int numFaces = strtol10(sz,&sz);
-
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = 1 ];
- aiMesh* mesh = pScene->mMeshes[0] = new aiMesh();
- aiFace* faces = mesh->mFaces = new aiFace [mesh->mNumFaces = numFaces];
-
- std::vector<aiVector3D> tempPositions(numVertices);
-
- // now read all vertex lines
- for (unsigned int i = 0; i< numVertices;++i)
- {
- if (!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("OFF: The number of verts in the header is incorrect");
- break;
- }
- aiVector3D& v = tempPositions[i];
-
- sz = line; SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)v.x); SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)v.y); SkipSpaces(&sz);
- fast_atof_move(sz,(float&)v.z);
- }
-
-
- // First find out how many vertices we'll need
- const char* old = buffer;
- for (unsigned int i = 0; i< mesh->mNumFaces;++i)
- {
- if (!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("OFF: The number of faces in the header is incorrect");
- break;
- }
- sz = line;SkipSpaces(&sz);
- if (!(faces->mNumIndices = strtol10(sz,&sz)) || faces->mNumIndices > 9)
- {
- DefaultLogger::get()->error("OFF: Faces with zero indices aren't allowed");
- --mesh->mNumFaces;
- continue;
- }
- mesh->mNumVertices += faces->mNumIndices;
- ++faces;
- }
-
- if (!mesh->mNumVertices)
- throw DeadlyImportError("OFF: There are no valid faces");
-
- // allocate storage for the output vertices
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
-
- // second: now parse all face indices
- buffer = old;faces = mesh->mFaces;
- for (unsigned int i = 0, p = 0; i< mesh->mNumFaces;)
- {
- if (!GetNextLine(buffer,line))break;
-
- unsigned int idx;
- sz = line;SkipSpaces(&sz);
- if (!(idx = strtol10(sz,&sz)) || idx > 9)
- continue;
-
- faces->mIndices = new unsigned int [faces->mNumIndices];
- for (unsigned int m = 0; m < faces->mNumIndices;++m)
- {
- SkipSpaces(&sz);
- if ((idx = strtol10(sz,&sz)) >= numVertices)
- {
- DefaultLogger::get()->error("OFF: Vertex index is out of range");
- idx = numVertices-1;
- }
- faces->mIndices[m] = p++;
- *verts++ = tempPositions[idx];
- }
- ++i;
- ++faces;
- }
-
- // generate the output node graph
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<OFFRoot>");
- pScene->mRootNode->mMeshes = new unsigned int [pScene->mRootNode->mNumMeshes = 1];
- pScene->mRootNode->mMeshes[0] = 0;
-
- // generate a default material
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = 1];
- MaterialHelper* pcMat = new MaterialHelper();
-
- aiColor4D clr(0.6f,0.6f,0.6f,1.0f);
- pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- pScene->mMaterials[0] = pcMat;
-
- const int twosided =1;
- pcMat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
-}
-
-#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER
diff --git a/3rdparty/assimp/code/OFFLoader.h b/3rdparty/assimp/code/OFFLoader.h
deleted file mode 100644
index 995e0e3a..00000000
--- a/3rdparty/assimp/code/OFFLoader.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file OFFLoader.h
- * @brief Declaration of the OFF importer class.
- */
-#ifndef AI_OFFLOADER_H_INCLUDED
-#define AI_OFFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the Object File Format (.off)
-*/
-class OFFImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- OFFImporter();
-
- /** Destructor, private as well */
- ~OFFImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/3rdparty/assimp/code/ObjFileData.h b/3rdparty/assimp/code/ObjFileData.h
deleted file mode 100644
index 37f91f10..00000000
--- a/3rdparty/assimp/code/ObjFileData.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef OBJ_FILEDATA_H_INC
-#define OBJ_FILEDATA_H_INC
-
-#include <vector>
-#include <map>
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-
-namespace Assimp
-{
-
-namespace ObjFile
-{
-// ------------------------------------------------------------------------------------------------
-struct Object;
-struct Face;
-struct Material;
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Face
-//! \brief Datastructure for a simple obj-face, descripes discredisation and materials
-struct Face
-{
- typedef std::vector<unsigned int> IndexArray;
-
- //! Primitive type
- int m_PrimitiveType;
- //! Vertex indices
- IndexArray *m_pVertices;
- //! Normal indices
- IndexArray *m_pNormals;
- //! Texture coordinates indices
- IndexArray *m_pTexturCoords;
- //! Pointer to assigned material
- Material *m_pMaterial;
-
- //! \brief Default constructor
- //! \param pVertices Pointer to assigned vertex indexbuffer
- //! \param pNormals Pointer to assigned normals indexbuffer
- //! \param pTexCoords Pointer to assigned texture indexbuffer
- Face( std::vector<unsigned int> *pVertices,
- std::vector<unsigned int> *pNormals,
- std::vector<unsigned int> *pTexCoords) :
- m_PrimitiveType( 2 ),
- m_pVertices( pVertices ),
- m_pNormals( pNormals ),
- m_pTexturCoords( pTexCoords ),
- m_pMaterial( 0L )
- {
- // empty
- }
-
- //! \brief Destructor
- ~Face()
- {
- delete m_pVertices;
- m_pVertices = NULL;
- delete m_pNormals;
- m_pNormals = NULL;
- delete m_pTexturCoords;
- m_pTexturCoords = NULL;
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Object
-//! \brief Stores all objects of an objfile object definition
-struct Object
-{
- enum ObjectType
- {
- ObjType,
- GroupType
- };
-
- //! Object name
- std::string m_strObjName;
- //! Transformation matrix, stored in OpenGL format
- aiMatrix4x4 m_Transformation;
- //! All sub-objects referenced by this object
- std::vector<Object*> m_SubObjects;
- /// Assigned meshes
- std::vector<unsigned int> m_Meshes;
-
- //! \brief Default constructor
- Object() :
- m_strObjName("")
- {
- // empty
- }
-
- //! \brief Destructor
- ~Object()
- {
- for (std::vector<Object*>::iterator it = m_SubObjects.begin();
- it != m_SubObjects.end(); ++it)
- {
- delete *it;
- }
- m_SubObjects.clear();
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Material
-//! \brief Data structure to store all material specific data
-struct Material
-{
- //! Name of material description
- aiString MaterialName;
-
- //! Texture names
- aiString texture;
- aiString textureSpecular;
- aiString textureAmbient;
- aiString textureBump;
- aiString textureSpecularity;
- aiString textureOpacity;
-
- //! Ambient color
- aiColor3D ambient;
- //! Diffuse color
- aiColor3D diffuse;
- //! Speculao color
- aiColor3D specular;
- //! Alpha value
- float alpha;
- //! Shineness factor
- float shineness;
- //! Illumination model
- int illumination_model;
- //! Index of refraction
- float ior;
-
- //! Constructor
- Material()
- : diffuse (0.6f,0.6f,0.6f)
- , alpha (1.f)
- , shineness (0.0f)
- , illumination_model (1)
- , ior (1.f)
- {
- // empty
- }
-
- // Destructor
- ~Material()
- {
- // empty
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Mesh
-//! \brief Data structure to store a mesh
-struct Mesh
-{
- static const unsigned int NoMaterial = 999999999;
-
- /// Array with pointer to all stored faces
- std::vector<Face*> m_Faces;
- /// Assigned material
- Material *m_pMaterial;
- /// Number of stored indices.
- unsigned int m_uiNumIndices;
- /// Number of UV
- unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
- /// Material index.
- unsigned int m_uiMaterialIndex;
- /// True, if normals are stored.
- bool m_hasNormals;
- /// Constructor
- Mesh() :
- m_pMaterial(NULL),
- m_uiNumIndices(0),
- m_uiMaterialIndex( NoMaterial ),
- m_hasNormals(false)
- {
- memset(m_uiUVCoordinates, 0, sizeof( unsigned int ) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
- }
-
- /// Destructor
- ~Mesh()
- {
- for (std::vector<Face*>::iterator it = m_Faces.begin();
- it != m_Faces.end(); ++it)
- {
- delete *it;
- }
-
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Model
-//! \brief Data structure to store all obj-specific model datas
-struct Model
-{
- typedef std::map<std::string*, std::vector<unsigned int>* > GroupMap;
- typedef std::map<std::string*, std::vector<unsigned int>* >::iterator GroupMapIt;
- typedef std::map<std::string*, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
-
- //! Model name
- std::string m_ModelName;
- //! List ob assigned objects
- std::vector<Object*> m_Objects;
- //! Pointer to current object
- ObjFile::Object *m_pCurrent;
- //! Pointer to current material
- ObjFile::Material *m_pCurrentMaterial;
- //! Pointer to default material
- ObjFile::Material *m_pDefaultMaterial;
- //! Vector with all generated materials
- std::vector<std::string> m_MaterialLib;
- //! Vector with all generated group
- std::vector<std::string> m_GroupLib;
- //! Vector with all generated vertices
- std::vector<aiVector3D> m_Vertices;
- //! vector with all generated normals
- std::vector<aiVector3D> m_Normals;
- //! Groupmap
- GroupMap m_Groups;
- //! Group to face id assignment
- std::vector<unsigned int> *m_pGroupFaceIDs;
- //! Active group
- std::string m_strActiveGroup;
- //! Vector with generated texture coordinates
- std::vector<aiVector2D> m_TextureCoord;
- //! Current mesh instance
- Mesh *m_pCurrentMesh;
- //! Vector with stored meshes
- std::vector<Mesh*> m_Meshes;
- //! Material map
- std::map<std::string, Material*> m_MaterialMap;
-
-
- //! \brief Default constructor
- Model() :
- m_ModelName(""),
- m_pCurrent(NULL),
- m_pCurrentMaterial(NULL),
- m_pDefaultMaterial(NULL),
- m_strActiveGroup(""),
- m_pCurrentMesh(NULL)
- {
- // empty
- }
-
- //! \brief Destructor
- ~Model()
- {
- // Clear all stored object instances
- for (std::vector<Object*>::iterator it = m_Objects.begin();
- it != m_Objects.end(); ++it)
- {
- delete *it;
- }
- m_Objects.clear();
-
- // Clear all stored mesh instances
- for (std::vector<Mesh*>::iterator it = m_Meshes.begin();
- it != m_Meshes.end(); ++it)
- {
- delete *it;
- }
-
- m_Meshes.clear();
-
- for (GroupMapIt it = m_Groups.begin();
- it != m_Groups.end(); ++it)
- {
- delete it->second;
- }
-
- m_Groups.clear();
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace ObjFile
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/ObjFileImporter.cpp b/3rdparty/assimp/code/ObjFileImporter.cpp
deleted file mode 100644
index 87030ea2..00000000
--- a/3rdparty/assimp/code/ObjFileImporter.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include "DefaultIOSystem.h"
-#include "ObjFileImporter.h"
-#include "ObjFileParser.h"
-#include "ObjFileData.h"
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-// Default constructor
-ObjFileImporter::ObjFileImporter() :
- m_Buffer(),
- m_pRootObject( NULL ),
- m_strAbsPath( "" )
-{
- DefaultIOSystem io;
- m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-ObjFileImporter::~ObjFileImporter()
-{
- // Release root object instance
- if (NULL != m_pRootObject)
- {
- delete m_pRootObject;
- m_pRootObject = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if file is an obj file.
-bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const
-{
- if (!checkSig) //Check File Extension
- {
- return SimpleExtensionCheck(pFile,"obj");
- }
- else //Check file Header
- {
- const char* tokens[] = {"mtllib","usemtl","vt ","vn ","o "};
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 5);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Obj-file import implementation
-void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- DefaultIOSystem io;
-
- // Read file into memory
- const std::string mode = "rb";
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
- if (NULL == file.get())
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- // Get the filesize and vaslidate it, throwing an exception when failes
- size_t fileSize = file->FileSize();
- if ( fileSize < 16)
- throw DeadlyImportError( "OBJ-file is too small.");
-
- // Allocate buffer and read file into it
- TextFileToBuffer(file.get(),m_Buffer);
-
- // Get the model name
- std::string strModelName;
- std::string::size_type pos = pFile.find_last_of( "\\/" );
- if ( pos != std::string::npos )
- {
- strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
- }
- else
- {
- strModelName = pFile;
- }
-
- // parse the file into a temporary representation
- ObjFileParser parser(m_Buffer, strModelName, pIOHandler);
-
- // And create the proper return structures out of it
- CreateDataFromImport(parser.GetModel(), pScene);
-
- // Clean up allocated storage for the next import
- m_Buffer.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Create the data from parsed obj-file
-void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene)
-{
- if (0L == pModel)
- return;
-
- // Create the root node of the scene
- pScene->mRootNode = new aiNode;
- if ( !pModel->m_ModelName.empty() )
- {
- // Set the name of the scene
- pScene->mRootNode->mName.Set(pModel->m_ModelName);
- }
- else
- {
- // This is an error, so break down the application
- ai_assert(false);
- }
-
- // Create nodes for the whole scene
- std::vector<aiMesh*> MeshArray;
- for (size_t index = 0; index < pModel->m_Objects.size(); index++)
- {
- createNodes(pModel, pModel->m_Objects[ index ], index, pScene->mRootNode, pScene, MeshArray);
- }
-
- // Create mesh pointer buffer for this scene
- if (pScene->mNumMeshes > 0)
- {
- pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
- for (size_t index =0; index < MeshArray.size(); index++)
- {
- pScene->mMeshes [ index ] = MeshArray[ index ];
- }
- }
-
- // Create all materials
- createMaterials( pModel, pScene );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all nodes of the model
-aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject,
- unsigned int /*uiMeshIndex*/,
- aiNode *pParent, aiScene* pScene,
- std::vector<aiMesh*> &MeshArray )
-{
- ai_assert( NULL != pModel );
- if ( NULL == pObject )
- return NULL;
-
- // Store older mesh size to be able to computate mesh offsets for new mesh instances
- const size_t oldMeshSize = MeshArray.size();
- aiNode *pNode = new aiNode;
- pNode->mName = aiString(pObject->m_strObjName);
-
- if (pParent != NULL)
- appendChildToParentNode(pParent, pNode);
-
-
- for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
- {
- unsigned int meshId = pObject->m_Meshes[ i ];
- aiMesh *pMesh = new aiMesh;
- createTopology( pModel, pObject, meshId, pMesh );
- if ( pMesh->mNumVertices > 0 )
- {
- MeshArray.push_back( pMesh );
- }
- else
- {
- delete pMesh;
- }
- }
-
- // Create all nodes from the sub-objects stored in the current object
- if ( !pObject->m_SubObjects.empty() )
- {
- size_t numChilds = pObject->m_SubObjects.size();
- pNode->mNumChildren = static_cast<unsigned int>( numChilds );
- pNode->mChildren = new aiNode*[ numChilds ];
- pNode->mNumMeshes = 1;
- pNode->mMeshes = new unsigned int[ 1 ];
- }
-
- // Set mesh instances into scene- and node-instances
- const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
- if ( meshSizeDiff > 0 )
- {
- pNode->mMeshes = new unsigned int[ meshSizeDiff ];
- pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
- size_t index = 0;
- for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
- {
- pNode->mMeshes[ index ] = pScene->mNumMeshes;
- pScene->mNumMeshes++;
- index++;
- }
- }
-
- return pNode;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Create topology data
-void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
- const ObjFile::Object* pData,
- unsigned int uiMeshIndex,
- aiMesh* pMesh )
-{
- // Checking preconditions
- ai_assert( NULL != pModel );
- if (NULL == pData)
- return;
-
- // Create faces
- ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
- ai_assert( NULL != pObjMesh );
- pMesh->mNumFaces = static_cast<unsigned int>( pObjMesh->m_Faces.size() );
- if ( pMesh->mNumFaces > 0 )
- {
- pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
- if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial )
- {
- pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
- }
-
- // Copy all data from all stored meshes
- for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
- {
- aiFace *pFace = &pMesh->mFaces[ index ];
- const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size();
- pFace->mNumIndices = (unsigned int) uiNumIndices;
- if (pFace->mNumIndices > 0)
- {
- pFace->mIndices = new unsigned int[ uiNumIndices ];
- ObjFile::Face::IndexArray *pIndexArray = pObjMesh->m_Faces[ index ]->m_pVertices;
- ai_assert ( NULL != pIndexArray );
- for ( size_t a=0; a<pFace->mNumIndices; a++ )
- {
- pFace->mIndices[ a ] = pIndexArray->at( a );
- }
- }
- else
- {
- pFace->mIndices = NULL;
- }
- }
- }
-
- // Create mesh vertices
- createVertexArray(pModel, pData, uiMeshIndex, pMesh);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates a vertex array
-void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
- const ObjFile::Object* pCurrentObject,
- unsigned int uiMeshIndex,
- aiMesh* pMesh)
-{
- // Checking preconditions
- ai_assert( NULL != pCurrentObject );
-
- // Break, if no faces are stored in object
- if ( pCurrentObject->m_Meshes.empty() )
- return;
-
- // Get current mesh
- ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
- if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1)
- return;
-
- // Copy vertices of this mesh instance
- pMesh->mNumVertices = (unsigned int) pObjMesh->m_uiNumIndices;
- pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
-
- // Allocate buffer for normal vectors
- if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals )
- pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
-
- // Allocate buffer for texture coordinates
- if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
- {
- pMesh->mNumUVComponents[ 0 ] = 2;
- pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
- }
-
- // Copy vertices, normals and textures into aiMesh instance
- unsigned int newIndex = 0;
- for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ )
- {
- // Get destination face
- aiFace *pDestFace = &pMesh->mFaces[ index ];
-
- // Get source face
- ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
-
- // Copy all index arrays
- for ( size_t vertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ )
- {
- const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
- ai_assert( vertex < pModel->m_Vertices.size() );
- pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
-
- // Copy all normals
- if ( !pSourceFace->m_pNormals->empty() )
- {
- const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
- ai_assert( normal < pModel->m_Normals.size() );
- pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
- }
-
- // Copy all texture coordinates
- if ( !pModel->m_TextureCoord.empty() )
- {
- if ( !pSourceFace->m_pTexturCoords->empty() )
- {
- const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
- ai_assert( tex < pModel->m_TextureCoord.size() );
- for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ )
- {
- if ( pMesh->mNumUVComponents[ i ] > 0 )
- {
- aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
- pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
- }
- }
- }
- }
-
- ai_assert( pMesh->mNumVertices > newIndex );
- pDestFace->mIndices[ vertexIndex ] = newIndex;
- ++newIndex;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts all stored meshes
-void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
-{
- iNumMeshes = 0;
- if ( rObjects.empty() )
- return;
-
- iNumMeshes += static_cast<unsigned int>( rObjects.size() );
- for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
- it != rObjects.end();
- ++it)
- {
- if (!(*it)->m_SubObjects.empty())
- {
- countObjects((*it)->m_SubObjects, iNumMeshes);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the material
-void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene )
-{
- ai_assert( NULL != pScene );
- if ( NULL == pScene )
- return;
-
- const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
- pScene->mNumMaterials = 0;
- if ( pModel->m_MaterialLib.empty() )
- return;
-
- pScene->mMaterials = new aiMaterial*[ numMaterials ];
- for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
- {
- Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
-
- // Store material name
- std::map<std::string, ObjFile::Material*>::const_iterator it;
- it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
-
- // No material found, use the default material
- if ( pModel->m_MaterialMap.end() == it )
- continue;
-
- ObjFile::Material *pCurrentMaterial = (*it).second;
- mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
-
- // convert illumination model
- int sm = 0;
- switch (pCurrentMaterial->illumination_model)
- {
- case 0:
- sm = aiShadingMode_NoShading;
- break;
- case 1:
- sm = aiShadingMode_Gouraud;
- break;
- case 2:
- sm = aiShadingMode_Phong;
- break;
- default:
- sm = aiShadingMode_Gouraud;
- DefaultLogger::get()->error("OBJ/MTL: Unexpected illumination model (0-2 recognized)");
- }
- mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
-
- // multiplying the specular exponent with 2 seems to yield better results
- pCurrentMaterial->shineness *= 4.f;
-
- // Adding material colors
- mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT );
- mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
- mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR );
- mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS );
- mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY );
-
- // Adding refraction index
- mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI );
-
- // Adding textures
- if ( 0 != pCurrentMaterial->texture.length )
- mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- if ( 0 != pCurrentMaterial->textureAmbient.length )
- mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
-
- if ( 0 != pCurrentMaterial->textureSpecular.length )
- mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
-
- if ( 0 != pCurrentMaterial->textureBump.length )
- mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
-
- if ( 0 != pCurrentMaterial->textureOpacity.length )
- mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
-
- if ( 0 != pCurrentMaterial->textureSpecularity.length )
- mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
-
- // Store material property info in material array in scene
- pScene->mMaterials[ pScene->mNumMaterials ] = mat;
- pScene->mNumMaterials++;
- }
-
- // Test number of created materials.
- ai_assert( pScene->mNumMaterials == numMaterials );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Appends this node to the parent node
-void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
-{
- // Checking preconditions
- ai_assert( NULL != pParent );
- ai_assert( NULL != pChild );
-
- // Assign parent to child
- pChild->mParent = pParent;
- size_t sNumChildren = 0;
-
- // If already children was assigned to the parent node, store them in a
- std::vector<aiNode*> temp;
- if (pParent->mChildren != NULL)
- {
- sNumChildren = pParent->mNumChildren;
- ai_assert( 0 != sNumChildren );
- for (size_t index = 0; index < pParent->mNumChildren; index++)
- {
- temp.push_back(pParent->mChildren [ index ] );
- }
- delete [] pParent->mChildren;
- }
-
- // Copy node instances into parent node
- pParent->mNumChildren++;
- pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
- for (size_t index = 0; index < pParent->mNumChildren-1; index++)
- {
- pParent->mChildren[ index ] = temp [ index ];
- }
- pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/3rdparty/assimp/code/ObjFileImporter.h b/3rdparty/assimp/code/ObjFileImporter.h
deleted file mode 100644
index 10f3cf0b..00000000
--- a/3rdparty/assimp/code/ObjFileImporter.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-#ifndef OBJ_FILE_IMPORTER_H_INC
-#define OBJ_FILE_IMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include <vector>
-
-struct aiMesh;
-struct aiNode;
-
-namespace Assimp
-{
-
-namespace ObjFile
-{
-struct Object;
-struct Model;
-}
-
-// ------------------------------------------------------------------------------------------------
-/// \class ObjFileImporter
-/// \brief Imports a waveform obj file
-// ------------------------------------------------------------------------------------------------
-class ObjFileImporter :
- BaseImporter
-{
- friend class Importer;
-
-protected:
- /// \brief Default constructor
- ObjFileImporter();
-
- /// \brief Destructor
- ~ObjFileImporter();
-
-public:
- /// \brief Returns whether the class can handle the format of the given file.
- /// \remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
-
- //! \brief Appends the supported extention.
- void GetExtensionList(std::set<std::string>& extensions);
-
- //! \brief File import implementation.
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- //! \brief Create the data from imported content.
- void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
-
- //! \brief Creates all nodes stored in imported content.
- aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int uiMeshIndex,
- aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
-
- //! \brief Creates topology data like faces and meshes for the geometry.
- void createTopology(const ObjFile::Model* pModel, const ObjFile::Object* pData,
- unsigned int uiMeshIndex, aiMesh* pMesh);
-
- //! \brief Creates vertices from model.
- void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
- unsigned int uiMeshIndex, aiMesh* pMesh);
-
- //! \brief Object counter helper method.
- void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
-
- //! \brief Material creation.
- void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
-
- //! \brief Appends a child node to a parentnode and updates the datastructures.
- void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
-
- //! \brief TODO!
- void createAnimations();
-
-private:
- //! Data buffer
- std::vector<char> m_Buffer;
- //! Pointer to root object instance
- ObjFile::Object *m_pRootObject;
- //! Absolute pathname of model in filesystem
- std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-//
-inline void ObjFileImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("obj");
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/ObjFileMtlImporter.cpp b/3rdparty/assimp/code/ObjFileMtlImporter.cpp
deleted file mode 100644
index 67863dc0..00000000
--- a/3rdparty/assimp/code/ObjFileMtlImporter.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include "ObjFileMtlImporter.h"
-#include "ObjTools.h"
-#include "ObjFileData.h"
-#include "fast_atof.h"
-
-namespace Assimp {
-
-// -------------------------------------------------------------------
-// Constructor
-ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
- const std::string & /*strAbsPath*/,
- ObjFile::Model *pModel ) :
- m_DataIt( buffer.begin() ),
- m_DataItEnd( buffer.end() ),
- m_pModel( pModel ),
- m_uiLine( 0 )
-{
- ai_assert( NULL != m_pModel );
- if ( NULL == m_pModel->m_pDefaultMaterial )
- {
- m_pModel->m_pDefaultMaterial = new ObjFile::Material;
- m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
- }
- load();
-}
-
-// -------------------------------------------------------------------
-// Destructor
-ObjFileMtlImporter::~ObjFileMtlImporter()
-{
- // empty
-}
-
-// -------------------------------------------------------------------
-// Private copy constructor
-ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & /* rOther */ )
-{
- // empty
-}
-
-// -------------------------------------------------------------------
-// Private copy constructor
-ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & /*rOther */ )
-{
- return *this;
-}
-
-// -------------------------------------------------------------------
-// Loads the material description
-void ObjFileMtlImporter::load()
-{
- if ( m_DataIt == m_DataItEnd )
- return;
-
- while ( m_DataIt != m_DataItEnd )
- {
- switch (*m_DataIt)
- {
- case 'K':
- {
- ++m_DataIt;
- if (*m_DataIt == 'a') // Ambient color
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient );
- }
- else if (*m_DataIt == 'd') // Diffuse color
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse );
- }
- else if (*m_DataIt == 's')
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->specular );
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'd': // Alpha value
- {
- ++m_DataIt;
- getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'N': // Shineness
- {
- ++m_DataIt;
- switch(*m_DataIt)
- {
- case 's':
- ++m_DataIt;
- getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
- break;
- case 'i': //Index Of refraction
- ++m_DataIt;
- getFloatValue(m_pModel->m_pCurrentMaterial->ior);
- break;
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- break;
- }
- break;
-
-
- case 'm': // Texture
- case 'b': // quick'n'dirty - for 'bump' sections
- {
- getTexture();
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'n': // New material name
- {
- createMaterial();
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'i': // Illumination model
- {
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- default:
- {
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
- }
- }
-}
-
-// -------------------------------------------------------------------
-// Loads a color definition
-void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
-{
- ai_assert( NULL != pColor );
-
- float r, g, b;
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
- pColor->r = r;
-
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
- pColor->g = g;
-
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
- pColor->b = b;
-}
-
-// -------------------------------------------------------------------
-// Loads the kind of illumination model.
-void ObjFileMtlImporter::getIlluminationModel( int &illum_model )
-{
- m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
- illum_model = atoi(m_buffer);
-}
-
-// -------------------------------------------------------------------
-// Loads a single float value.
-void ObjFileMtlImporter::getFloatValue( float &value )
-{
- m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
- value = (float) fast_atof(m_buffer);
-}
-
-// -------------------------------------------------------------------
-// Creates a material from loaded data.
-void ObjFileMtlImporter::createMaterial()
-{
- std::string strName( "" );
- m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strName );
- if ( m_DataItEnd == m_DataIt )
- return;
-
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName );
- if ( m_pModel->m_MaterialMap.end() == it)
- {
- // New Material created
- m_pModel->m_pCurrentMaterial = new ObjFile::Material();
- m_pModel->m_pCurrentMaterial->MaterialName.Set( strName );
- m_pModel->m_MaterialLib.push_back( strName );
- m_pModel->m_MaterialMap[ strName ] = m_pModel->m_pCurrentMaterial;
- }
- else
- {
- // Use older material
- m_pModel->m_pCurrentMaterial = (*it).second;
- }
-}
-
-// -------------------------------------------------------------------
-// Gets a texture name from data.
-void ObjFileMtlImporter::getTexture()
-{
- aiString *out = NULL;
-
- // FIXME: just a quick'n'dirty hack, consider cleanup later
-
- // Diffuse texture
- if (!ASSIMP_strincmp(&(*m_DataIt),"map_kd",6))
- out = & m_pModel->m_pCurrentMaterial->texture;
-
- // Ambient texture
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6))
- out = & m_pModel->m_pCurrentMaterial->textureAmbient;
-
- // Specular texture
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ks",6))
- out = & m_pModel->m_pCurrentMaterial->textureSpecular;
-
- // Opacity texture
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_d",5))
- out = & m_pModel->m_pCurrentMaterial->textureOpacity;
-
- // Ambient texture
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6))
- out = & m_pModel->m_pCurrentMaterial->textureAmbient;
-
- // Bump texture
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_bump",8) || !ASSIMP_strincmp(&(*m_DataIt),"bump",4))
- out = & m_pModel->m_pCurrentMaterial->textureBump;
-
- // Specularity scaling (glossiness)
- else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ns",6))
- out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
-
- else
- {
- DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type");
- return;
- }
-
- std::string strTexture;
- m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strTexture );
- out->Set( strTexture );
-}
-
-// -------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/3rdparty/assimp/code/ObjFileMtlImporter.h b/3rdparty/assimp/code/ObjFileMtlImporter.h
deleted file mode 100644
index 8b83a014..00000000
--- a/3rdparty/assimp/code/ObjFileMtlImporter.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------*/
-#ifndef OBJFILEMTLIMPORTER_H_INC
-#define OBJFILEMTLIMPORTER_H_INC
-
-#include <vector>
-#include <string>
-
-struct aiColor3D;
-
-namespace Assimp
-{
-
-namespace ObjFile
-{
-struct Model;
-struct Material;
-
-}
-
-
-/**
- * @class ObjFileMtlImporter
- * @brief Loads the material description from a mtl file.
- */
-class ObjFileMtlImporter
-{
-public:
- static const size_t BUFFERSIZE = 2048;
- typedef std::vector<char> DataArray;
- typedef std::vector<char>::iterator DataArrayIt;
- typedef std::vector<char>::const_iterator ConstDataArrayIt;
-
-public:
- //! \brief Default constructor
- ObjFileMtlImporter( std::vector<char> &buffer, const std::string &strAbsPath,
- ObjFile::Model *pModel );
-
- //! \brief DEstructor
- ~ObjFileMtlImporter();
-
-private:
- /// Copy constructor, empty.
- ObjFileMtlImporter(const ObjFileMtlImporter &rOther);
- /// \brief Assignment operator, returns only a reference of this instance.
- ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther);
- /// Load the whole material description
- void load();
- /// Get color data.
- void getColorRGBA( aiColor3D *pColor);
- /// Get illumination model from loaded data
- void getIlluminationModel( int &illum_model );
- /// Gets a float value from data.
- void getFloatValue( float &value );
- /// Creates a new material from loaded data.
- void createMaterial();
- /// Get texture name from loaded data.
- void getTexture();
-
-private:
- //! Absolute pathname
- std::string m_strAbsPath;
- //! Data iterator showing to the current position in data buffer
- DataArrayIt m_DataIt;
- //! Data iterator to end of buffer
- DataArrayIt m_DataItEnd;
- //! USed model instance
- ObjFile::Model *m_pModel;
- //! Current line in file
- unsigned int m_uiLine;
- //! Helper buffer
- char m_buffer[BUFFERSIZE];
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/ObjFileParser.cpp b/3rdparty/assimp/code/ObjFileParser.cpp
deleted file mode 100644
index 98214ba4..00000000
--- a/3rdparty/assimp/code/ObjFileParser.cpp
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include "ObjFileParser.h"
-#include "ObjFileMtlImporter.h"
-#include "ObjTools.h"
-#include "ObjFileData.h"
-#include "fast_atof.h"
-#include "../include/aiTypes.h"
-#include "DefaultIOSystem.h"
-
-namespace Assimp
-{
-
-// -------------------------------------------------------------------
-const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
-// fix: changed that to our standard default name
-
-// -------------------------------------------------------------------
-// Constructor with loaded data and directories.
-ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem *io ) :
- m_DataIt(Data.begin()),
- m_DataItEnd(Data.end()),
- m_pModel(NULL),
- m_uiLine(0),
- m_pIO( io )
-{
- // Create the model instance to store all the data
- m_pModel = new ObjFile::Model();
- m_pModel->m_ModelName = strModelName;
-
- m_pModel->m_pDefaultMaterial = new ObjFile::Material();
- m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL );
- m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL );
- m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
-
- // Start parsing the file
- parseFile();
-}
-
-// -------------------------------------------------------------------
-// Destrcutor.
-ObjFileParser::~ObjFileParser()
-{
- delete m_pModel->m_pDefaultMaterial;
- m_pModel->m_pDefaultMaterial = NULL;
-
- delete m_pModel;
- m_pModel = NULL;
-}
-
-// -------------------------------------------------------------------
-// Returns a pointer to the model instance.
-ObjFile::Model *ObjFileParser::GetModel() const
-{
- return m_pModel;
-}
-
-// -------------------------------------------------------------------
-// File parsing method.
-void ObjFileParser::parseFile()
-{
- if (m_DataIt == m_DataItEnd)
- return;
-
- while (m_DataIt != m_DataItEnd)
- {
- switch (*m_DataIt)
- {
- case 'v': // Parse a vertex texture coordinate
- {
- ++m_DataIt;
- if (*m_DataIt == ' ')
- {
- // Read in vertex definition
- getVector3(m_pModel->m_Vertices);
- }
- else if (*m_DataIt == 't')
- {
- // Read in texture coordinate (2D)
- ++m_DataIt;
- getVector2(m_pModel->m_TextureCoord);
- }
- else if (*m_DataIt == 'n')
- {
- // Read in normal vector definition
- ++m_DataIt;
- getVector3( m_pModel->m_Normals );
- }
- }
- break;
-
- case 'f': // Parse a face
- {
- getFace();
- }
- break;
-
- case '#': // Parse a comment
- {
- getComment();
- }
- break;
-
- case 'u': // Parse a material desc. setter
- {
- getMaterialDesc();
- }
- break;
-
- case 'm': // Parse a material library
- {
- getMaterialLib();
- }
- break;
-
- case 'g': // Parse group name
- {
- getGroupName();
- }
- break;
-
- case 's': // Parse group number
- {
- getGroupNumber();
- }
- break;
-
- case 'o': // Parse object name
- {
- getObjectName();
- }
- break;
-
- default:
- {
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
- }
- }
-}
-
-// -------------------------------------------------------------------
-// Copy the next word in a temporary buffer
-void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
-{
- size_t index = 0;
- m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
- while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
- {
- pBuffer[index] = *m_DataIt;
- index++;
- if (index == length-1)
- break;
- ++m_DataIt;
- }
- pBuffer[index] = '\0';
-}
-
-// -------------------------------------------------------------------
-// Copy the next line into a temporary buffer
-void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
-{
- size_t index = 0;
- while (m_DataIt != m_DataItEnd)
- {
- if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
- break;
-
- pBuffer[ index ] = *m_DataIt;
- ++index;
- ++m_DataIt;
- }
- pBuffer[ index ] = '\0';
-}
-
-// -------------------------------------------------------------------
-// Get values for a new 3D vector instance
-void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array)
-{
- float x, y, z;
- copyNextWord(m_buffer, BUFFERSIZE);
- x = (float) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, BUFFERSIZE);
- y = (float) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, BUFFERSIZE);
- z = (float) fast_atof(m_buffer);
-
- point3d_array.push_back( aiVector3D( x, y, z ) );
- //skipLine();
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get values for a new 2D vector instance
-void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array )
-{
- float x, y;
- copyNextWord(m_buffer, BUFFERSIZE);
- x = (float) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, BUFFERSIZE);
- y = (float) fast_atof(m_buffer);
-
- point2d_array.push_back(aiVector2D(x, y));
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get values for a new face instance
-void ObjFileParser::getFace()
-{
- copyNextLine(m_buffer, BUFFERSIZE);
- if (m_DataIt == m_DataItEnd)
- return;
-
- char *pPtr = m_buffer;
- char *pEnd = &pPtr[BUFFERSIZE];
- pPtr = getNextToken<char*>(pPtr, pEnd);
- if (pPtr == '\0')
- return;
-
- std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
- std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
- std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
- bool hasNormal = false;
-
- bool vt = (!m_pModel->m_TextureCoord.empty());
- bool vn = (!m_pModel->m_Normals.empty());
- int iStep = 0, iPos = 0;
- while (pPtr != pEnd)
- {
- iStep = 1;
- if (*pPtr == '\0')
- break;
-
- if (*pPtr=='\r')
- break;
-
- if (*pPtr=='/' )
- {
- if (iPos == 0)
- {
- //if there are no texturecoordinates in the obj file but normals
- if (!vt && vn) {
- iPos = 1;
- iStep++;
- }
- }
- iPos++;
- }
- else if ( isSeparator(*pPtr) )
- {
- iPos = 0;
- }
- else
- {
- //OBJ USES 1 Base ARRAYS!!!!
- const int iVal = atoi( pPtr );
- int tmp = iVal;
- while ( ( tmp = tmp / 10 )!=0 )
- ++iStep;
-
- if ( iVal > 0 )
- {
- // Store parsed index
- if ( 0 == iPos )
- {
- pIndices->push_back( iVal-1 );
- }
- else if ( 1 == iPos )
- {
- pTexID->push_back( iVal-1 );
- }
- else if ( 2 == iPos )
- {
- pNormalID->push_back( iVal-1 );
- hasNormal = true;
- }
- else
- {
- reportErrorTokenInFace();
- }
- }
- }
- for ( int i=0; i<iStep; i++ )
- ++pPtr;
- }
-
- ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID );
-
- // Set active material, if one set
- if (NULL != m_pModel->m_pCurrentMaterial)
- face->m_pMaterial = m_pModel->m_pCurrentMaterial;
- else
- face->m_pMaterial = m_pModel->m_pDefaultMaterial;
-
- // Create a default object, if nothing there
- if ( NULL == m_pModel->m_pCurrent )
- createObject( "defaultobject" );
-
- // Assign face to mesh
- if ( NULL == m_pModel->m_pCurrentMesh )
- {
- createMesh();
- }
-
- // Store the face
- m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
- m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size();
- m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size();
- if ( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal )
- {
- m_pModel->m_pCurrentMesh->m_hasNormals = true;
- }
- // Skip the rest of the line
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get values for a new material description
-void ObjFileParser::getMaterialDesc()
-{
- // Get next data for material data
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if (m_DataIt == m_DataItEnd)
- return;
-
- char *pStart = &(*m_DataIt);
- while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
- ++m_DataIt;
-
- // Get name
- std::string strName(pStart, &(*m_DataIt));
- if ( strName.empty())
- return;
-
- // Search for material
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName );
- if ( it == m_pModel->m_MaterialMap.end() )
- {
- // Not found, use default material
- m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
- }
- else
- {
- // Found, using detected material
- m_pModel->m_pCurrentMaterial = (*it).second;
- if ( needsNewMesh( strName ))
- {
- createMesh();
- }
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName );
- }
-
- // Skip rest of line
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get a comment, values will be skipped
-void ObjFileParser::getComment()
-{
- bool running = true;
- while (running)
- {
- if ( '\n' == (*m_DataIt) || m_DataIt == m_DataItEnd )
- {
- ++m_DataIt;
- break;
- }
- else
- {
- ++m_DataIt;
- }
- }
-}
-
-// -------------------------------------------------------------------
-// Get material library from file.
-void ObjFileParser::getMaterialLib()
-{
- // Translate tuple
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if (m_DataIt == m_DataItEnd)
- return;
-
- char *pStart = &(*m_DataIt);
- while (!isNewLine(*m_DataIt))
- m_DataIt++;
-
- // Check for existence
- const std::string strMatName(pStart, &(*m_DataIt));
- IOStream *pFile = m_pIO->Open(strMatName);
-
- if (!pFile )
- {
- DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName);
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- return;
- }
-
- // Import material library data from file
- std::vector<char> buffer;
- BaseImporter::TextFileToBuffer(pFile,buffer);
- m_pIO->Close( pFile );
-
- // Importing the material library
- ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel );
-}
-
-// -------------------------------------------------------------------
-// Set a new material definition as the current material.
-void ObjFileParser::getNewMaterial()
-{
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
- if ( m_DataIt == m_DataItEnd )
- return;
-
- char *pStart = &(*m_DataIt);
- std::string strMat( pStart, *m_DataIt );
- while ( isSeparator( *m_DataIt ) )
- m_DataIt++;
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
- if ( it == m_pModel->m_MaterialMap.end() )
- {
- // Show a warning, if material was not found
- DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
- m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
- }
- else
- {
- // Set new material
- if ( needsNewMesh( strMat ) )
- {
- createMesh();
- }
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
- }
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
-{
- int mat_index = -1;
- if ( strMaterialName.empty() )
- return mat_index;
- for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
- {
- if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
- {
- mat_index = (int)index;
- break;
- }
- }
- return mat_index;
-}
-
-// -------------------------------------------------------------------
-// Getter for a group name.
-void ObjFileParser::getGroupName()
-{
- // Get next word from data buffer
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
- if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
- return;
-
- // Store groupname in group library
- char *pStart = &(*m_DataIt);
- while ( !isSeparator(*m_DataIt) )
- m_DataIt++;
- std::string strGroupName(pStart, &(*m_DataIt));
-
- // Change active group, if necessary
- if ( m_pModel->m_strActiveGroup != strGroupName )
- {
- // Search for already existing entry
- ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(&strGroupName);
-
- // We are mapping groups into the object structure
- createObject( strGroupName );
-
- // New group name, creating a new entry
- if (it == m_pModel->m_Groups.end())
- {
- std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
- m_pModel->m_Groups[ &strGroupName ] = pFaceIDArray;
- m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
- }
- else
- {
- m_pModel->m_pGroupFaceIDs = (*it).second;
- }
- m_pModel->m_strActiveGroup = strGroupName;
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Not supported
-void ObjFileParser::getGroupNumber()
-{
- // Not used
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Stores values for a new object instance, name will be used to
-// identify it.
-void ObjFileParser::getObjectName()
-{
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if (m_DataIt == m_DataItEnd)
- return;
- char *pStart = &(*m_DataIt);
- while ( !isSeparator( *m_DataIt ) )
- ++m_DataIt;
-
- std::string strObjectName(pStart, &(*m_DataIt));
- if (!strObjectName.empty())
- {
- // Reset current object
- m_pModel->m_pCurrent = NULL;
-
- // Search for actual object
- for (std::vector<ObjFile::Object*>::const_iterator it = m_pModel->m_Objects.begin();
- it != m_pModel->m_Objects.end();
- ++it)
- {
- if ((*it)->m_strObjName == strObjectName)
- {
- m_pModel->m_pCurrent = *it;
- break;
- }
- }
-
- // Allocate a new object, if current one was not found before
- if ( NULL == m_pModel->m_pCurrent )
- createObject(strObjectName);
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-// -------------------------------------------------------------------
-// Creates a new object instance
-void ObjFileParser::createObject(const std::string &strObjectName)
-{
- ai_assert( NULL != m_pModel );
- //ai_assert( !strObjectName.empty() );
-
- m_pModel->m_pCurrent = new ObjFile::Object;
- m_pModel->m_pCurrent->m_strObjName = strObjectName;
- m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
-
- createMesh();
-
- if ( m_pModel->m_pCurrentMaterial )
- {
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex =
- getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data );
- m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
- }
-}
-// -------------------------------------------------------------------
-// Creates a new mesh
-void ObjFileParser::createMesh()
-{
- ai_assert( NULL != m_pModel );
- m_pModel->m_pCurrentMesh = new ObjFile::Mesh;
- m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
- unsigned int meshId = m_pModel->m_Meshes.size()-1;
- if ( NULL != m_pModel->m_pCurrent )
- {
- m_pModel->m_pCurrent->m_Meshes.push_back( meshId );
- }
- else
- {
- DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance.");
- }
-}
-
-// -------------------------------------------------------------------
-// Returns true, if a new mesh must be created.
-bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
-{
- if (m_pModel->m_pCurrentMesh == 0)
- {
- // No mesh data yet
- return true;
- }
- bool newMat = false;
- int matIdx = getMaterialIndex( rMaterialName );
- unsigned int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
- if ( curMatIdx != ObjFile::Mesh::NoMaterial || curMatIdx != (unsigned int)matIdx )
- {
- // New material -> only one material per mesh, so we need to create a new
- // material
- newMat = true;
- }
- return newMat;
-}
-
-// -------------------------------------------------------------------
-// Shows an error in parsing process.
-void ObjFileParser::reportErrorTokenInFace()
-{
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
-}
-
-// -------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/3rdparty/assimp/code/ObjFileParser.h b/3rdparty/assimp/code/ObjFileParser.h
deleted file mode 100644
index 8ad34f68..00000000
--- a/3rdparty/assimp/code/ObjFileParser.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-#ifndef OBJ_FILEPARSER_H_INC
-#define OBJ_FILEPARSER_H_INC
-
-#include <vector>
-#include <string>
-#include <map>
-
-namespace Assimp
-{
-
-namespace ObjFile
-{
-struct Model;
-struct Object;
-struct Material;
-struct Point3;
-struct Point2;
-}
-class ObjFileImporter;
-class IOSystem;
-
-/// \class ObjFileParser
-/// \brief Parser for a obj waveform file
-class ObjFileParser
-{
-public:
- static const size_t BUFFERSIZE = 4096;
- typedef std::vector<char> DataArray;
- typedef std::vector<char>::iterator DataArrayIt;
- typedef std::vector<char>::const_iterator ConstDataArrayIt;
-
-public:
- /// \brief Constructor with data array.
- ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
- /// \brief Destructor
- ~ObjFileParser();
- /// \brief Model getter.
- ObjFile::Model *GetModel() const;
-
-private:
- /// Parse the loadedfile
- void parseFile();
- /// Method to copy the new delimited word in the current line.
- void copyNextWord(char *pBuffer, size_t length);
- /// Method to copy the new line.
- void copyNextLine(char *pBuffer, size_t length);
- /// Stores the following 3d vector.
- void getVector3( std::vector<aiVector3D> &point3d_array );
- /// Stores the following 3d vector.
- void getVector2(std::vector<aiVector2D> &point2d_array);
- /// Stores the following face.
- void getFace();
- void getMaterialDesc();
- /// Gets a comment.
- void getComment();
- /// Gets a a material library.
- void getMaterialLib();
- /// Creates a new material.
- void getNewMaterial();
- /// Gets the groupname from file.
- void getGroupName();
- /// Gets the group number from file.
- void getGroupNumber();
- /// Returns the index of the material. Is -1 if not material was found.
- int getMaterialIndex( const std::string &strMaterialName );
- /// Parse object name
- void getObjectName();
- /// Creates a new object.
- void createObject(const std::string &strObjectName);
- /// Creates a new mesh.
- void createMesh();
- /// Returns true, if a new mesh instance must be created.
- bool needsNewMesh( const std::string &rMaterialName );
- /// Error report in token
- void reportErrorTokenInFace();
-
-private:
- /// Default material name
- static const std::string DEFAULT_MATERIAL;
- //! Iterator to current position in buffer
- DataArrayIt m_DataIt;
- //! Iterator to end position of buffer
- DataArrayIt m_DataItEnd;
- //! Pointer to model instance
- ObjFile::Model *m_pModel;
- //! Current line (for debugging)
- unsigned int m_uiLine;
- //! Helper buffer
- char m_buffer[BUFFERSIZE];
- /// Pointer to IO system instance.
- IOSystem *m_pIO;
-};
-
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/ObjTools.h b/3rdparty/assimp/code/ObjTools.h
deleted file mode 100644
index 2fdfa0f1..00000000
--- a/3rdparty/assimp/code/ObjTools.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file ObjTools.h
- * @brief Some helpful templates for text parsing
- */
-#ifndef OBJ_TOOLS_H_INC
-#define OBJ_TOOLS_H_INC
-
-#include "fast_atof.h"
-
-namespace Assimp
-{
-
-/** @brief Returns true, if the last entry of the buffer is reached.
- * @param it Iterator of current position.
- * @param end Iterator with end of buffer.
- * @return true, if the end of the buffer is reached.
- */
-template<class char_t>
-inline bool isEndOfBuffer( char_t it, char_t end )
-{
- if ( it == end )
- {
- return true;
- }
- else
- {
- end--;
- }
- return ( it == end );
-}
-
-/** @brief Returns true, if token is a space on any supported platform
-* @param token Token to search in
-* @return true, if token is a space
-*/
-inline bool isSeparator( char token )
-{
- return ( token == ' ' ||
- token == '\n' ||
- token == '\f' ||
- token == '\r' ||
- token == '\t' );
-}
-
-/** @brief Returns true, fi token id a new line marking token.
- * @param token Token to search in
- * @return true, if token is a newline token.
- */
-inline bool isNewLine( char token )
-{
- return ( token == '\n' || token == '\f' || token == '\r' );
-}
-
-/** @brief Returns next word separated by a space
- * @param pBuffer Pointer to data buffer
- * @param pEnd Pointer to end of buffer
- * @return Pointer to next space
- */
-template<class Char_T>
-inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
-{
- while ( !isEndOfBuffer( pBuffer, pEnd ) )
- {
- if ( !isSeparator( *pBuffer ) || isNewLine( *pBuffer ) )
- break;
- pBuffer++;
- }
- return pBuffer;
-}
-
-/** @brief Returns ponter a next token
- * @param pBuffer Pointer to data buffer
- * @param pEnd Pointer to end of buffer
- * @return Pointer to next token
- */
-template<class Char_T>
-inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
-{
- while ( !isEndOfBuffer( pBuffer, pEnd ) )
- {
- if ( isSeparator( *pBuffer ) )
- break;
- pBuffer++;
- }
- return getNextWord( pBuffer, pEnd );
-}
-
-/** @brief Skips a line
- * @param it Iterator set to current position
- * @param end Iterator set to end of scratch buffer for readout
- * @param uiLine Current linenumber in format
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
-{
- while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) )
- ++it;
- if ( it != end )
- {
- ++it;
- ++uiLine;
- }
- // fix .. from time to time there are spaces at the beginning of a material line
- while ( it != end && (*it == '\t' || *it == ' ') )
- ++it;
- return it;
-}
-
-/** @brief Get a name, must be separated with a blank.
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param name Separated name
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t getName( char_t it, char_t end, std::string &name )
-{
- name = "";
- it = getNextToken<char_t>( it, end );
- if ( isEndOfBuffer( it, end ) )
- return end;
-
- char *pStart = &( *it );
- while ( !isEndOfBuffer( it, end ) && !isSeparator( *it ) )
- ++it;
-
- // Get name
- std::string strName( pStart, &(*it) );
- if ( strName.empty() )
- return it;
- else
- name = strName;
-
- return it;
-}
-
-/** @brief Get next word from given line
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param pBuffer Buffer for next word
- * @param length Buffer length
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length )
-{
- size_t index = 0;
- it = getNextWord<char_t>( it, end );
- while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
- {
- pBuffer[index] = *it ;
- index++;
- if (index == length-1)
- break;
- ++it;
- }
- pBuffer[ index ] = '\0';
- return it;
-}
-
-/** @brief Get next float from given line
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param value Separated float value.
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t getFloat( char_t it, char_t end, float &value )
-{
- static const size_t BUFFERSIZE = 1024;
- char buffer[ BUFFERSIZE ];
- it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
- value = (float) fast_atof( buffer );
-
- return it;
-}
-
-} // Namespace Assimp
-
-#endif
diff --git a/3rdparty/assimp/code/OgreImporter.cpp b/3rdparty/assimp/code/OgreImporter.cpp
deleted file mode 100644
index 07bb2c5e..00000000
--- a/3rdparty/assimp/code/OgreImporter.cpp
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file OgreImporter.cpp
- * @brief Implementation of the Ogre XML (.mesh.xml) loader.
- */
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include <vector>
-#include <sstream>
-using namespace std;
-
-//#include "boost/format.hpp"
-//#include "boost/foreach.hpp"
-//using namespace boost;
-
-#include "TinyFormatter.h"
-
-#include "OgreImporter.h"
-#include "irrXMLWrapper.h"
-
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-
-bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const
-{
- if (!checkSig)//Check File Extension
- {
- std::string extension("mesh.xml");
- int l=extension.length();
- return pFile.substr(pFile.length()-l, l)==extension;
- }
- else//Check file Header
- {
- const char* tokens[] = {"<mesh>"};
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
- }
-}
-
-
-
-void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler)
-{
- m_CurrentFilename=pFile;
- m_CurrentIOHandler=pIOHandler;
- m_CurrentScene=pScene;
-
- //Open the File:
- boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile));
- if ( file.get() == NULL)
- throw DeadlyImportError("Failed to open file "+pFile+".");
-
- //Read the Mesh File:
- boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- XmlReader* MeshFile = irr::io::createIrrXMLReader(mIOWrapper.get());
- if (!MeshFile)//parse the xml file
- throw DeadlyImportError("Failed to create XML Reader for "+pFile);
-
-
- DefaultLogger::get()->debug("Mesh File opened");
-
- //Read root Node:
- if (!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="mesh"))
- {
- throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName());
- }
-
- //Go to the submeshs:
- if (!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="submeshes"))
- {
- throw DeadlyImportError("No <submeshes> node in <mesh> node! "+pFile);
- }
-
-
- //-------------------Read the submeshs and materials:-----------------------
- std::list<boost::shared_ptr<SubMesh> > SubMeshes;
- vector<aiMaterial*> Materials;
- XmlRead(MeshFile);
- while (MeshFile->getNodeName()==string("submesh"))
- {
- SubMesh* theSubMesh=new SubMesh();
- theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material");
- DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
- ReadSubMesh(*theSubMesh, MeshFile);
-
- //just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
- //so it is important to do this before pushing the mesh in the vector!
- theSubMesh->MaterialIndex=SubMeshes.size();
-
- SubMeshes.push_back(boost::shared_ptr<SubMesh>(theSubMesh));
-
- //Load the Material:
- aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName);
-
- //Set the Material:
- Materials.push_back(MeshMat);
- }
-
- if (SubMeshes.empty())
- throw DeadlyImportError("no submesh loaded!");
- if (SubMeshes.size()!=Materials.size())
- throw DeadlyImportError("materialcount doesn't match mesh count!");
-
- //____________________________________________________________
-
-
- //----------------Load the skeleton: -------------------------------
- vector<Bone> Bones;
- vector<Animation> Animations;
- if (MeshFile->getNodeName()==string("skeletonlink"))
- {
- string SkeletonFile=GetAttribute<string>(MeshFile, "name");
- LoadSkeleton(SkeletonFile, Bones, Animations);
- }
- else
- {
- DefaultLogger::get()->warn("No skeleton file will be loaded");
- DefaultLogger::get()->warn(MeshFile->getNodeName());
- }
- //__________________________________________________________________
-
-
- //----------------- Now fill the Assimp scene ---------------------------
-
- //put the aiMaterials in the scene:
- m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()];
- m_CurrentScene->mNumMaterials=Materials.size();
- for (unsigned int i=0; i<Materials.size(); ++i)
- m_CurrentScene->mMaterials[i]=Materials[i];
-
- //create the aiMehs...
- vector<aiMesh*> aiMeshes;
- BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes)
- {
- aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones));
- }
- //... and put them in the scene:
- m_CurrentScene->mNumMeshes=aiMeshes.size();
- m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()];
- memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size());
-
- //Create the root node
- m_CurrentScene->mRootNode=new aiNode("root");
-
- //link the meshs with the root node:
- m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()];
- m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size();
- for (unsigned int i=0; i<SubMeshes.size(); ++i)
- m_CurrentScene->mRootNode->mMeshes[i]=i;
-
-
-
- CreateAssimpSkeleton(Bones, Animations);
- PutAnimationsInScene(Bones, Animations);
- //___________________________________________________________
-}
-
-
-
-void OgreImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("mesh.xml");
-}
-
-
-void OgreImporter::SetupProperties(const Importer* pImp)
-{
- m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material");
-}
-
-void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader)
-{
- XmlRead(Reader);
- //TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order
- //of faces and geometry changed, and not if we have more than one of one
- while (Reader->getNodeName()==string("faces") || string(Reader->getNodeName())=="geometry" || Reader->getNodeName()==string("boneassignments"))
- {
- if (string(Reader->getNodeName())=="faces")//Read the face list
- {
- //some info logging:
- unsigned int NumFaces=GetAttribute<int>(Reader, "count");
- stringstream ss; ss <<"Submesh has " << NumFaces << " Faces.";
- DefaultLogger::get()->debug(ss.str());
-
- while (XmlRead(Reader) && Reader->getNodeName()==string("face"))
- {
- Face NewFace;
- NewFace.VertexIndices[0]=GetAttribute<int>(Reader, "v1");
- NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2");
- NewFace.VertexIndices[2]=GetAttribute<int>(Reader, "v3");
- if (Reader->getAttributeValue("v4"))//this should be supported in the future
- {
- throw DeadlyImportError("Submesh has quads, only traingles are supported!");
- }
- theSubMesh.FaceList.push_back(NewFace);
- }
-
- }//end of faces
- else if (string(Reader->getNodeName())=="geometry")//Read the vertexdata
- {
- //some info logging:
- unsigned int NumVertices=GetAttribute<int>(Reader, "vertexcount");
- stringstream ss; ss<<"VertexCount: "<<NumVertices;
- DefaultLogger::get()->debug(ss.str());
-
- //General Informations about vertices
- XmlRead(Reader);
- if (!(Reader->getNodeName()==string("vertexbuffer")))
- {
- throw DeadlyImportError("vertexbuffer node is not first in geometry node!");
- }
- theSubMesh.HasPositions=GetAttribute<bool>(Reader, "positions");
- theSubMesh.HasNormals=GetAttribute<bool>(Reader, "normals");
- if (!Reader->getAttributeValue("texture_coords"))//we can have 1 or 0 uv channels, and if the mesh has no uvs, it also doesn't have the attribute
- theSubMesh.NumUvs=0;
- else
- theSubMesh.NumUvs=GetAttribute<int>(Reader, "texture_coords");
- if (theSubMesh.NumUvs>1)
- throw DeadlyImportError("too many texcoords (just 1 supported!)");
-
- //read all the vertices:
- XmlRead(Reader);
- while (Reader->getNodeName()==string("vertex"))
- {
- //read all vertex attributes:
-
- //Position
- if (theSubMesh.HasPositions)
- {
- XmlRead(Reader);
- aiVector3D NewPos;
- NewPos.x=GetAttribute<float>(Reader, "x");
- NewPos.y=GetAttribute<float>(Reader, "y");
- NewPos.z=GetAttribute<float>(Reader, "z");
- theSubMesh.Positions.push_back(NewPos);
- }
-
- //Normal
- if (theSubMesh.HasNormals)
- {
- XmlRead(Reader);
- aiVector3D NewNormal;
- NewNormal.x=GetAttribute<float>(Reader, "x");
- NewNormal.y=GetAttribute<float>(Reader, "y");
- NewNormal.z=GetAttribute<float>(Reader, "z");
- theSubMesh.Normals.push_back(NewNormal);
- }
-
- //Uv:
- if (1==theSubMesh.NumUvs)
- {
- XmlRead(Reader);
- aiVector3D NewUv;
- NewUv.x=GetAttribute<float>(Reader, "u");
- NewUv.y=GetAttribute<float>(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so!
- theSubMesh.Uvs.push_back(NewUv);
- }
- XmlRead(Reader);
- }
-
- }//end of "geometry
-
-
- else if (string(Reader->getNodeName())=="boneassignments")
- {
- theSubMesh.Weights.resize(theSubMesh.Positions.size());
- while (XmlRead(Reader) && Reader->getNodeName()==string("vertexboneassignment"))
- {
- Weight NewWeight;
- unsigned int VertexId=GetAttribute<int>(Reader, "vertexindex");
- NewWeight.BoneId=GetAttribute<int>(Reader, "boneindex");
- NewWeight.Value=GetAttribute<float>(Reader, "weight");
- theSubMesh.BonesUsed=max(theSubMesh.BonesUsed, NewWeight.BoneId+1);//calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0)
-
- theSubMesh.Weights[VertexId].push_back(NewWeight);
-
- //XmlRead(Reader);//Once i had this line, and than i got only every second boneassignment, but my first test models had even boneassignment counts, so i thougt, everything would work. And yes, i HATE irrXML!!!
- }
-
- }//end of boneassignments
- }
- DefaultLogger::get()->debug((Formatter::format(),
- "Positionen: ",theSubMesh.Positions.size(),
- " Normale: ",theSubMesh.Normals.size(),
- " TexCoords: ",theSubMesh.Uvs.size()
- ));
- DefaultLogger::get()->warn(Reader->getNodeName());
-
-
-
- //---------------Make all Vertexes unique: (this is required by assimp)-----------------------
- vector<Face> UniqueFaceList(theSubMesh.FaceList.size());
- unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^
- vector<aiVector3D> UniquePositions(UniqueVertexCount);
- vector<aiVector3D> UniqueNormals(UniqueVertexCount);
- vector<aiVector3D> UniqueUvs(UniqueVertexCount);
- vector< vector<Weight> > UniqueWeights((theSubMesh.Weights.size() ? UniqueVertexCount : 0));
-
- for (unsigned int i=0; i<theSubMesh.FaceList.size(); ++i)
- {
- //We precalculate the index vlaues her, because we need them in all vertex attributes
- unsigned int Vertex1=theSubMesh.FaceList[i].VertexIndices[0];
- unsigned int Vertex2=theSubMesh.FaceList[i].VertexIndices[1];
- unsigned int Vertex3=theSubMesh.FaceList[i].VertexIndices[2];
-
- UniquePositions[3*i+0]=theSubMesh.Positions[Vertex1];
- UniquePositions[3*i+1]=theSubMesh.Positions[Vertex2];
- UniquePositions[3*i+2]=theSubMesh.Positions[Vertex3];
-
- UniqueNormals[3*i+0]=theSubMesh.Normals[Vertex1];
- UniqueNormals[3*i+1]=theSubMesh.Normals[Vertex2];
- UniqueNormals[3*i+2]=theSubMesh.Normals[Vertex3];
-
- if (1==theSubMesh.NumUvs)
- {
- UniqueUvs[3*i+0]=theSubMesh.Uvs[Vertex1];
- UniqueUvs[3*i+1]=theSubMesh.Uvs[Vertex2];
- UniqueUvs[3*i+2]=theSubMesh.Uvs[Vertex3];
- }
-
- if (theSubMesh.Weights.size()) {
- UniqueWeights[3*i+0]=theSubMesh.Weights[Vertex1];
- UniqueWeights[3*i+1]=theSubMesh.Weights[Vertex2];
- UniqueWeights[3*i+2]=theSubMesh.Weights[Vertex3];
- }
-
- //The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...)
- UniqueFaceList[i].VertexIndices[0]=3*i+0;
- UniqueFaceList[i].VertexIndices[1]=3*i+1;
- UniqueFaceList[i].VertexIndices[2]=3*i+2;
- }
- //_________________________________________________________________________________________
-
- //now we have the unique datas, but want them in the SubMesh, so we swap all the containers:
- theSubMesh.FaceList.swap(UniqueFaceList);
- theSubMesh.Positions.swap(UniquePositions);
- theSubMesh.Normals.swap(UniqueNormals);
- theSubMesh.Uvs.swap(UniqueUvs);
- theSubMesh.Weights.swap(UniqueWeights);
-
- //------------- normalize weights -----------------------------
- //The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not,
- //so we have to make this sure:
- for (unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
- {
- float WeightSum=0.0f;
- for (unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
- {
- WeightSum+=theSubMesh.Weights[VertexId][BoneId].Value;
- }
-
- //check if the sum is too far away from 1
- if (WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f)
- {
- //normalize all weights:
- for (unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
- {
- theSubMesh.Weights[VertexId][BoneId].Value/=WeightSum;
- }
- }
- }
- //_________________________________________________________
-}
-
-
-aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& Bones) const
-{
- // const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
-
- aiMesh* NewAiMesh=new aiMesh();
-
- //Positions
- NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()];
- memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D));
- NewAiMesh->mNumVertices=theSubMesh.Positions.size();
-
- //Normals
- NewAiMesh->mNormals=new aiVector3D[theSubMesh.Normals.size()];
- memcpy(NewAiMesh->mNormals, &theSubMesh.Normals[0], theSubMesh.Normals.size()*sizeof(aiVector3D));
-
- //Uvs
- if (0!=theSubMesh.NumUvs)
- {
- NewAiMesh->mNumUVComponents[0]=2;
- NewAiMesh->mTextureCoords[0]= new aiVector3D[theSubMesh.Uvs.size()];
- memcpy(NewAiMesh->mTextureCoords[0], &theSubMesh.Uvs[0], theSubMesh.Uvs.size()*sizeof(aiVector3D));
- }
-
-
- //---------------------------------------- Bones --------------------------------------------
-
- //Copy the weights in in Bone-Vertices Struktur
- //(we have them in a Vertex-Bones Structur, this is much easier for making them unique, which is required by assimp
- vector< vector<aiVertexWeight> > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices
- for (unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
- {
- for (unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
- {
- aiVertexWeight NewWeight;
- NewWeight.mVertexId=VertexId;//the current Vertex, we can't use the Id form the submehs weights, because they are bone id's
- NewWeight.mWeight=theSubMesh.Weights[VertexId][BoneId].Value;
- aiWeights[theSubMesh.Weights[VertexId][BoneId].BoneId].push_back(NewWeight);
- }
- }
-
-
-
- vector<aiBone*> aiBones;
- aiBones.reserve(theSubMesh.BonesUsed);//the vector might be smaller, because there might be empty bones (bones that are not attached to any vertex)
-
- //create all the bones and fill them with informations
- for (unsigned int i=0; i<theSubMesh.BonesUsed; ++i)
- {
- if (aiWeights[i].size()>0)
- {
- aiBone* NewBone=new aiBone();
- NewBone->mNumWeights=aiWeights[i].size();
- NewBone->mWeights=new aiVertexWeight[aiWeights[i].size()];
- memcpy(NewBone->mWeights, &(aiWeights[i][0]), sizeof(aiVertexWeight)*aiWeights[i].size());
- NewBone->mName=Bones[i].Name;//The bone list should be sorted after its id's, this was done in LoadSkeleton
- NewBone->mOffsetMatrix=Bones[i].BoneToWorldSpace;
-
- aiBones.push_back(NewBone);
- }
- }
- NewAiMesh->mNumBones=aiBones.size();
-
- // mBones must be NULL if mNumBones is non 0 or the validation fails.
- if (aiBones.size()) {
- NewAiMesh->mBones=new aiBone* [aiBones.size()];
- memcpy(NewAiMesh->mBones, &(aiBones[0]), aiBones.size()*sizeof(aiBone*));
- }
-
- //______________________________________________________________________________________________________
-
-
-
- //Faces
- NewAiMesh->mFaces=new aiFace[theSubMesh.FaceList.size()];
- for (unsigned int i=0; i<theSubMesh.FaceList.size(); ++i)
- {
- NewAiMesh->mFaces[i].mNumIndices=3;
- NewAiMesh->mFaces[i].mIndices=new unsigned int[3];
-
- NewAiMesh->mFaces[i].mIndices[0]=theSubMesh.FaceList[i].VertexIndices[0];
- NewAiMesh->mFaces[i].mIndices[1]=theSubMesh.FaceList[i].VertexIndices[1];
- NewAiMesh->mFaces[i].mIndices[2]=theSubMesh.FaceList[i].VertexIndices[2];
- }
- NewAiMesh->mNumFaces=theSubMesh.FaceList.size();
-
- //Link the material:
- NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh
-
- return NewAiMesh;
-}
-
-
-void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations) const
-{
- //const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
-
-
- //most likely the skeleton file will only end with .skeleton
- //But this is a xml reader, so we need: .skeleton.xml
- FileName+=".xml";
-
- DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName);
-
- //Open the File:
- boost::scoped_ptr<IOStream> File(m_CurrentIOHandler->Open(FileName));
- if (NULL==File.get())
- throw DeadlyImportError("Failed to open skeleton file "+FileName+".");
-
- //Read the Mesh File:
- boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(File.get()));
- XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get());
- if (!SkeletonFile)
- throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName);
-
- //Quick note: Whoever read this should know this one thing: irrXml fucking sucks!!!
-
- XmlRead(SkeletonFile);
- if (string("skeleton")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName);
-
-
-
- //------------------------------------load bones-----------------------------------------
- XmlRead(SkeletonFile);
- if (string("bones")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("No bones node in skeleton "+FileName);
-
- XmlRead(SkeletonFile);
-
- while (string("bone")==SkeletonFile->getNodeName())
- {
- //TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what....
-
- //read a new bone:
- Bone NewBone;
- NewBone.Id=GetAttribute<int>(SkeletonFile, "id");
- NewBone.Name=GetAttribute<string>(SkeletonFile, "name");
-
- //load the position:
- XmlRead(SkeletonFile);
- if (string("position")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("Position is not first node in Bone!");
- NewBone.Position.x=GetAttribute<float>(SkeletonFile, "x");
- NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y");
- NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z");
-
- //Rotation:
- XmlRead(SkeletonFile);
- if (string("rotation")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("Rotation is not the second node in Bone!");
- NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
- XmlRead(SkeletonFile);
- if (string("axis")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("No axis specified for bone rotation!");
- NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
- NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
- NewBone.RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
-
- //append the newly loaded bone to the bone list
- Bones.push_back(NewBone);
-
- //Proceed to the next bone:
- XmlRead(SkeletonFile);
- }
- //The bones in the file a not neccesarly ordered by there id's so we do it now:
- std::sort(Bones.begin(), Bones.end());
-
- //now the id of each bone should be equal to its position in the vector:
- //so we do a simple check:
- {
- bool IdsOk=true;
- for (int i=0; i<static_cast<signed int>(Bones.size()); ++i)//i is signed, because all Id's are also signed!
- {
- if (Bones[i].Id!=i)
- IdsOk=false;
- }
- if (!IdsOk)
- throw DeadlyImportError("Bone Ids are not valid!"+FileName);
- }
- DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size()));
- //________________________________________________________________________________
-
-
-
-
-
-
- //----------------------------load bonehierarchy--------------------------------
- if (string("bonehierarchy")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("no bonehierarchy node in "+FileName);
-
- DefaultLogger::get()->debug("loading bonehierarchy...");
- XmlRead(SkeletonFile);
- while (string("boneparent")==SkeletonFile->getNodeName())
- {
- string Child, Parent;
- Child=GetAttribute<string>(SkeletonFile, "bone");
- Parent=GetAttribute<string>(SkeletonFile, "parent");
-
- unsigned int ChildId, ParentId;
- ChildId=find(Bones.begin(), Bones.end(), Child)->Id;
- ParentId=find(Bones.begin(), Bones.end(), Parent)->Id;
-
- Bones[ChildId].ParentId=ParentId;
- Bones[ParentId].Children.push_back(ChildId);
-
- XmlRead(SkeletonFile);//i once forget this line, which led to an endless loop, did i mentioned, that irrxml sucks??
- }
- //_____________________________________________________________________________
-
-
- //--------- Calculate the WorldToBoneSpace Matrix recursivly for all bones: ------------------
- BOOST_FOREACH(Bone theBone, Bones)
- {
- if (-1==theBone.ParentId) //the bone is a root bone
- {
- theBone.CalculateBoneToWorldSpaceMatrix(Bones);
- }
- }
- //_______________________________________________________________________
-
-
- //---------------------------load animations-----------------------------
- if (string("animations")==SkeletonFile->getNodeName())//animations are optional values
- {
- DefaultLogger::get()->debug("Loading Animations");
- XmlRead(SkeletonFile);
- while (string("animation")==SkeletonFile->getNodeName())
- {
- Animation NewAnimation;
- NewAnimation.Name=GetAttribute<string>(SkeletonFile, "name");
- NewAnimation.Length=GetAttribute<float>(SkeletonFile, "length");
-
- //Load all Tracks
- XmlRead(SkeletonFile);
- if (string("tracks")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("no tracks node in animation");
- XmlRead(SkeletonFile);
- while (string("track")==SkeletonFile->getNodeName())
- {
- Track NewTrack;
- NewTrack.BoneName=GetAttribute<string>(SkeletonFile, "bone");
-
- //Load all keyframes;
- XmlRead(SkeletonFile);
- if (string("keyframes")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("no keyframes node!");
- XmlRead(SkeletonFile);
- while (string("keyframe")==SkeletonFile->getNodeName())
- {
- Keyframe NewKeyframe;
- NewKeyframe.Time=GetAttribute<float>(SkeletonFile, "time");
-
- //Position:
- XmlRead(SkeletonFile);
- if (string("translate")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("translate node not first in keyframe");
- NewKeyframe.Position.x=GetAttribute<float>(SkeletonFile, "x");
- NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y");
- NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z");
-
- //Rotation:
- XmlRead(SkeletonFile);
- if (string("rotate")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("rotate is not second node in keyframe");
- float RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
- aiVector3D RotationAxis;
- XmlRead(SkeletonFile);
- if (string("axis")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("No axis for keyframe rotation!");
- RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
- RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
- RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
- NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle);
-
- //Scaling:
- XmlRead(SkeletonFile);
- if (string("scale")!=SkeletonFile->getNodeName())
- throw DeadlyImportError("no scalling key in keyframe!");
- NewKeyframe.Scaling.x=GetAttribute<float>(SkeletonFile, "x");
- NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y");
- NewKeyframe.Scaling.z=GetAttribute<float>(SkeletonFile, "z");
-
-
- NewTrack.Keyframes.push_back(NewKeyframe);
- XmlRead(SkeletonFile);
- }
-
-
- NewAnimation.Tracks.push_back(NewTrack);
- }
-
- Animations.push_back(NewAnimation);
- }
- }
- //_____________________________________________________________________________
-
-}
-
-
-void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &/*Animations*/)
-{
- if (!m_CurrentScene->mRootNode)
- throw DeadlyImportError("No root node exists!!");
- if (0!=m_CurrentScene->mRootNode->mNumChildren)
- throw DeadlyImportError("Root Node already has childnodes!");
-
-
- //Createt the assimp bone hierarchy
- DefaultLogger::get()->debug("Root Bones");
- vector<aiNode*> RootBoneNodes;
- BOOST_FOREACH(Bone theBone, Bones)
- {
- if (-1==theBone.ParentId) //the bone is a root bone
- {
- DefaultLogger::get()->debug(theBone.Name);
- RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode));//which will recursily add all other nodes
- }
- }
- m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size();
- m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()];
- memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size());
-}
-
-
-void OgreImporter::PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations)
-{
- //-----------------Create the Assimp Animations --------------------
- if (Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called
- {
- m_CurrentScene->mNumAnimations=Animations.size();
- m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()];
- for (unsigned int i=0; i<Animations.size(); ++i)//create all animations
- {
- aiAnimation* NewAnimation=new aiAnimation();
- NewAnimation->mName=Animations[i].Name;
- NewAnimation->mDuration=Animations[i].Length;
- NewAnimation->mTicksPerSecond=1.0f;
-
- //Create all tracks in this animation
- NewAnimation->mNumChannels=Animations[i].Tracks.size();
- NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()];
- for (unsigned int j=0; j<Animations[i].Tracks.size(); ++j)
- {
- aiNodeAnim* NewNodeAnim=new aiNodeAnim();
- NewNodeAnim->mNodeName=Animations[i].Tracks[j].BoneName;
-
- //we need this, to acces the bones default pose, which we need to make keys absolute
- vector<Bone>::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName);
- aiMatrix4x4 t0, t1;
- aiMatrix4x4 DefBonePose=//The default bone pose doesnt have a scaling value
- aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0)
- * aiMatrix4x4::Translation(CurBone->Position, t1);
-
- //Create the keyframe arrays...
- unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size();
- NewNodeAnim->mNumPositionKeys=KeyframeCount;
- NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount];
- NewNodeAnim->mNumRotationKeys=KeyframeCount;
- NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount];
- NewNodeAnim->mNumScalingKeys=KeyframeCount;
- NewNodeAnim->mScalingKeys=new aiVectorKey[KeyframeCount];
-
- //...and fill them
- for (unsigned int k=0; k<KeyframeCount; ++k)
- {
- aiMatrix4x4 t2, t3;
-
- //Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key
- aiMatrix4x4 PoseToKey=aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2) //scale
- * aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix()) //rot
- * aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3); //pos
-
-
- //calculate the complete transformation from world space to bone space
- aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey;
-
- aiVector3D Pos;
- aiQuaternion Rot;
- aiVector3D Scale;
-
- CompleteTransform.Decompose(Scale, Rot, Pos);
-
-
- NewNodeAnim->mPositionKeys[k].mTime=Animations[i].Tracks[j].Keyframes[k].Time;
- NewNodeAnim->mPositionKeys[k].mValue=Pos;
-
- NewNodeAnim->mRotationKeys[k].mTime=Animations[i].Tracks[j].Keyframes[k].Time;
- NewNodeAnim->mRotationKeys[k].mValue=Rot;
-
- NewNodeAnim->mScalingKeys[k].mTime=Animations[i].Tracks[j].Keyframes[k].Time;
- NewNodeAnim->mScalingKeys[k].mValue=Scale;
- }
-
- NewAnimation->mChannels[j]=NewNodeAnim;
- }
-
- m_CurrentScene->mAnimations[i]=NewAnimation;
- }
- }
-//TODO: Auf nicht vorhandene Animationskeys achten!
-//#pragma warning (s.o.)
- //__________________________________________________________________
-}
-
-
-
-aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode) const
-{
- //const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
-
- //----Create the node for this bone and set its values-----
- aiNode* NewNode=new aiNode(Bones[BoneId].Name);
- NewNode->mParent=ParentNode;
-
- aiMatrix4x4 t0,t1;
- //create a matrix from the transformation values of the ogre bone
- NewNode->mTransformation=aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1)
- * aiMatrix4x4::Translation(Bones[BoneId].Position, t0)
-
- ;
- //__________________________________________________________
-
-
- //---------- recursivly create all children Nodes: ----------
- NewNode->mNumChildren=Bones[BoneId].Children.size();
- NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()];
- for (unsigned int i=0; i<Bones[BoneId].Children.size(); ++i)
- {
- NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode);
- }
- //____________________________________________________
-
-
- return NewNode;
-}
-
-
-void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &Bones)
-{
- //Calculate the matrix for this bone:
-
- aiMatrix4x4 t0,t1;
- aiMatrix4x4 Transf=aiMatrix4x4::Translation(-Position, t0)
- * aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1)
- ;
- if (-1==ParentId)
- {
- BoneToWorldSpace=Transf;
- }
- else
- {
- BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace;
- }
-
- //and recursivly for all children:
- BOOST_FOREACH(int theChildren, Children)
- {
- Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones);
- }
-}
-
-}//namespace Ogre
-}//namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/3rdparty/assimp/code/OgreImporter.h b/3rdparty/assimp/code/OgreImporter.h
deleted file mode 100644
index a6602441..00000000
--- a/3rdparty/assimp/code/OgreImporter.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#include "BaseImporter.h"
-
-#include <vector>
-
-#include "OgreXmlHelper.h"
-#include "irrXMLWrapper.h"
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-
-//
-///For the moment just triangles, no other polygon types!
-struct Face
-{
- unsigned int VertexIndices[3];
-};
-
-struct BoneAssignment
-{
- unsigned int BoneId;//this is, what we get from ogre
- std::string BoneName;//this is, what we need for assimp
-};
-
-///for a vertex->bone structur
-struct Weight
-{
- unsigned int BoneId;
- float Value;
-};
-
-/// Helper Class to describe an ogre-bone for the skeleton:
-/** All Id's are signed ints, because than we have -1 as a simple INVALID_ID Value (we start from 0 so 0 is a valid bone ID!*/
-struct Bone
-{
- int Id;
- int ParentId;
- std::string Name;
- aiVector3D Position;
- float RotationAngle;
- aiVector3D RotationAxis;
- std::vector<int> Children;
- aiMatrix4x4 BoneToWorldSpace;
-
- ///ctor
- Bone(): Id(-1), ParentId(-1), RotationAngle(0.0f) {}
- ///this operator is needed to sort the bones after Id's
- bool operator<(const Bone& rval) const
- {return Id<rval.Id; }
- ///this operator is needed to find a bone by its name in a vector<Bone>
- bool operator==(const std::string& rval) const
- {return Name==rval; }
- bool operator==(const aiString& rval) const
- {return Name==std::string(rval.data); }
-
- void CalculateBoneToWorldSpaceMatrix(std::vector<Bone>& Bones);
-
-};
-
-/// keyframe (bone transformation) from a track from a animation
-struct Keyframe
-{
- float Time;
- aiVector3D Position;
- aiQuaternion Rotation;
- aiVector3D Scaling;
-};
-
-///a track (keyframes for one bone) from an animation
-struct Track
-{
- std::string BoneName;
- std::vector<Keyframe> Keyframes;
-};
-
-///Describes an Ogre Animation
-struct Animation
-{
- std::string Name;
- float Length;
- std::vector<Track> Tracks;
-};
-
-///A submesh from Ogre
-struct SubMesh
-{
- std::string Name;
- std::string MaterialName;
- std::vector<Face> FaceList;
- std::vector<aiVector3D> Positions;
- bool HasPositions;
- std::vector<aiVector3D> Normals;
- bool HasNormals;
- std::vector<aiVector3D> Uvs;
- unsigned int NumUvs;//nearly always 2d, but assimp has always 3d texcoords
- std::vector< std::vector<Weight> > Weights;//a list of bones for each vertex
- int MaterialIndex;///< The Index in the Assimp Materialarray from the material witch is attached to this submesh
- unsigned int BonesUsed;//the highest index of a bone from a bone weight, this is needed to create the assimp bone structur (converting from Vertex-Bones to Bone-Vertices)
-
- SubMesh(): HasPositions(false), HasNormals(false), NumUvs(0), MaterialIndex(-1), BonesUsed(0) {}//initialize everything
-};
-
-///The Main Ogre Importer Class
-class OgreImporter : public BaseImporter
-{
-public:
- virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
- virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
- virtual void GetExtensionList(std::set<std::string>& extensions);
- virtual void SetupProperties(const Importer* pImp);
-private:
-
- /// Helper Functions to read parts of the XML File
- void ReadSubMesh(SubMesh& theSubMesh, XmlReader* Reader);//the submesh reference is the result value
-
- /// writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
- void LoadSkeleton(std::string FileName, std::vector<Bone> &Bones, std::vector<Animation> &Animations) const;
-
- /// converts the animations in aiAnimations and puts them into the scene
- void PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
-
- /// uses the bone data to convert a SubMesh into a aiMesh which will be created and returned
- aiMesh* CreateAssimpSubMesh(const SubMesh &theSubMesh, const std::vector<Bone>& Bones) const;
-
- //creates the aiskeleton in current scene
- void CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
-
- aiMaterial* LoadMaterial(const std::string MaterialName) const;
-
- ///Recursivly creates a filled aiNode from a given root bone
- aiNode* CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode) const;
-
- //Now we don't have to give theses parameters to all functions
- std::string m_CurrentFilename;
- std::string m_MaterialLibFilename;
- IOSystem* m_CurrentIOHandler;
- aiScene *m_CurrentScene;
-};
-
-}//namespace Ogre
-}//namespace Assimp
diff --git a/3rdparty/assimp/code/OgreImporterMaterial.cpp b/3rdparty/assimp/code/OgreImporterMaterial.cpp
deleted file mode 100644
index c3986e00..00000000
--- a/3rdparty/assimp/code/OgreImporterMaterial.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/**
-This file contains material related code. This is
-spilitted up from the main file OgreImporter.cpp
-to make it shorter easier to maintain.
-*/
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include <vector>
-#include <sstream>
-using namespace std;
-
-//#include "boost/format.hpp"
-//#include "boost/foreach.hpp"
-//using namespace boost;
-
-#include "OgreImporter.h"
-#include "irrXMLWrapper.h"
-#include "TinyFormatter.h"
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-
-
-aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
-{
- // const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
-
- MaterialHelper *NewMaterial=new MaterialHelper();
-
- aiString ts(MaterialName.c_str());
- NewMaterial->AddProperty(&ts, AI_MATKEY_NAME);
- /*For bettetr understanding of the material parser, here is a material example file:
-
- material Sarg
- {
- receive_shadows on
- technique
- {
- pass
- {
- ambient 0.500000 0.500000 0.500000 1.000000
- diffuse 0.640000 0.640000 0.640000 1.000000
- specular 0.500000 0.500000 0.500000 1.000000 12.500000
- emissive 0.000000 0.000000 0.000000 1.000000
- texture_unit
- {
- texture SargTextur.tga
- tex_address_mode wrap
- filtering linear linear none
- }
- }
- }
- }
-
- */
-
-
- const string MaterialFileName=m_CurrentFilename.substr(0, m_CurrentFilename.find('.'))+".material";
- DefaultLogger::get()->info("Trying to load " +MaterialFileName);
-
- //Read the file into memory and put it in a stringstream
- stringstream ss;
- {// after this block, the temporarly loaded data will be released
- IOStream* MatFilePtr=m_CurrentIOHandler->Open(MaterialFileName);
- if (NULL==MatFilePtr)
- {
- MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
- if (NULL==MatFilePtr)
- {
- DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
- return NewMaterial;
- }
- }
- boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr);
- vector<char> FileData(MaterialFile->FileSize());
- MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
- BaseImporter::ConvertToUTF8(FileData);
-
- ss << &FileData[0];
- }
-
- string Line;
- ss >> Line;
-// unsigned int Level=0;//Hierarchielevels in the material file, like { } blocks into another
- while (!ss.eof())
- {
- if (Line=="material")
- {
- ss >> Line;
- if (Line==MaterialName)//Load the next material
- {
- ss >> Line;
- if (Line!="{")
- throw DeadlyImportError("empty material!");
-
- while (Line!="}")//read until the end of the material
- {
- //Proceed to the first technique
- ss >> Line;
- if (Line=="technique")
- {
- ss >> Line;
- if (Line!="{")
- throw DeadlyImportError("empty technique!");
- while (Line!="}")//read until the end of the technique
- {
- ss >> Line;
- if (Line=="pass")
- {
- ss >> Line;
- if (Line!="{")
- throw DeadlyImportError("empty pass!");
- while (Line!="}")//read until the end of the pass
- {
- ss >> Line;
- if (Line=="ambient")
- {
- float r,g,b;
- ss >> r >> g >> b;
- const aiColor3D Color(r,g,b);
- NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_AMBIENT);
- }
- else if (Line=="diffuse")
- {
- float r,g,b;
- ss >> r >> g >> b;
- const aiColor3D Color(r,g,b);
- NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE);
- }
- else if (Line=="specular")
- {
- float r,g,b;
- ss >> r >> g >> b;
- const aiColor3D Color(r,g,b);
- NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_SPECULAR);
- }
- else if (Line=="emmisive")
- {
- float r,g,b;
- ss >> r >> g >> b;
- const aiColor3D Color(r,g,b);
- NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE);
- }
- else if (Line=="texture_unit")
- {
- ss >> Line;
- if (Line!="{")
- throw DeadlyImportError("empty texture unit!");
- while (Line!="}")//read until the end of the texture_unit
- {
- ss >> Line;
- if (Line=="texture")
- {
- ss >> Line;
- aiString ts(Line.c_str());
- NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
- }
- }//end of texture unit
- }
- }
- }
- }//end of technique
-
-
- }
-
-
- DefaultLogger::get()->info(Line);
- //read informations from a custom material:
- if (Line=="set")
- {
- ss >> Line;
- if (Line=="$specular")//todo load this values:
- {
- }
- if (Line=="$diffuse")
- {
- }
- if (Line=="$ambient")
- {
- }
- if (Line=="$colormap")
- {
- ss >> Line;
- aiString ts(Line.c_str());
- NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
- }
- if (Line=="$normalmap")
- {
- ss >> Line;
- aiString ts(Line.c_str());
- NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
- }
- }
- }//end of material
- }
- else {} //this is the wrong material, proceed the file until we reach the next material
- }
- ss >> Line;
- }
-
- return NewMaterial;
-}
-
-
-
-}//namespace Ogre
-}//namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/3rdparty/assimp/code/OgreXmlHelper.h b/3rdparty/assimp/code/OgreXmlHelper.h
deleted file mode 100644
index be72deee..00000000
--- a/3rdparty/assimp/code/OgreXmlHelper.h
+++ /dev/null
@@ -1,79 +0,0 @@
-
-#include "irrXMLWrapper.h"
-#include "fast_atof.h"
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-typedef irr::io::IrrXMLReader XmlReader;
-
-
-//------------Helper Funktion to Get a Attribute Save---------------
-template<typename t> inline t GetAttribute(XmlReader* Reader, std::string Name);
-
-/*
-{
- BOOST_STATIC_ASSERT(false);
- return t();
-}
-*/
-
-template<> inline int GetAttribute<int>(XmlReader* Reader, std::string Name)
-{
- const char* Value=Reader->getAttributeValue(Name.c_str());
- if (Value)
- return atoi(Value);
- else
- throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
-}
-
-template<> inline float GetAttribute<float>(XmlReader* Reader, std::string Name)
-{
- const char* Value=Reader->getAttributeValue(Name.c_str());
- if (Value)
- return fast_atof(Value);
- else
- throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
-}
-
-template<> inline std::string GetAttribute<std::string>(XmlReader* Reader, std::string Name)
-{
- const char* Value=Reader->getAttributeValue(Name.c_str());
- if (Value)
- return std::string(Value);
- else
- throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
-}
-
-template<> inline bool GetAttribute<bool>(XmlReader* Reader, std::string Name)
-{
- const char* Value=Reader->getAttributeValue(Name.c_str());
- if (Value)
- {
- if (Value==std::string("true"))
- return true;
- else if (Value==std::string("false"))
- return false;
- else
- throw DeadlyImportError(std::string("Bool value has invalid value: "+Name+" / "+Value+" / "+Reader->getNodeName()));
- }
- else
- throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
-}
-//__________________________________________________________________
-
-inline bool XmlRead(XmlReader* Reader)
-{
- do
- {
- if (!Reader->read())
- return false;
- }
- while (Reader->getNodeType()!=irr::io::EXN_ELEMENT);
- return true;
-}
-
-}//namespace Ogre
-}//namespace Assimp
diff --git a/3rdparty/assimp/code/OptimizeGraph.cpp b/3rdparty/assimp/code/OptimizeGraph.cpp
deleted file mode 100644
index a4829e12..00000000
--- a/3rdparty/assimp/code/OptimizeGraph.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file OptimizeGraph.cpp
- * @brief Implementation of the aiProcess_OptimizGraph step
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-
-using namespace Assimp;
-#include "OptimizeGraph.h"
-#include "ProcessHelper.h"
-#include "SceneCombiner.h"
-
-#define AI_RESERVED_NODE_NAME "$Reserved_And_Evil"
-
-/* AI_OG_USE_HASHING enables the use of hashing to speed-up std::set lookups.
- * The unhashed variant should be faster, except for *very* large data sets
- */
-#ifdef AI_OG_USE_HASHING
- // Use our standard hashing function to compute the hash
-# define AI_OG_GETKEY(str) SuperFastHash(str.data,str.length)
-#else
- // Otherwise hope that std::string will utilize a static buffer
- // for shorter node names. This would avoid endless heap copying.
-# define AI_OG_GETKEY(str) std::string(str.data)
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OptimizeGraphProcess::OptimizeGraphProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeGraphProcess::~OptimizeGraphProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool OptimizeGraphProcess::IsActive( unsigned int pFlags) const
-{
- return (0 != (pFlags & aiProcess_OptimizeGraph));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the postprocessing step
-void OptimizeGraphProcess::SetupProperties(const Importer* pImp)
-{
- // Get value of AI_CONFIG_PP_OG_EXCLUDE_LIST
- std::string tmp = pImp->GetPropertyString(AI_CONFIG_PP_OG_EXCLUDE_LIST,"");
- AddLockedNodeList(tmp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collect new children
-void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes)
-{
- nodes_in += nd->mNumChildren;
-
- // Process children
- std::list<aiNode*> child_nodes;
- for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
-
- CollectNewChildren(nd->mChildren[i],child_nodes);
- nd->mChildren[i] = NULL;
- }
-
- // Check whether we need this node; if not we can replace it by our own children (warn, danger of incest).
- if (locked.find(AI_OG_GETKEY(nd->mName)) == locked.end() ) {
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) {
-
- if (locked.find(AI_OG_GETKEY((*it)->mName)) == locked.end()) {
- (*it)->mTransformation = nd->mTransformation * (*it)->mTransformation;
- nodes.push_back(*it);
-
- it = child_nodes.erase(it);
- continue;
- }
- ++it;
- }
-
- if (nd->mNumMeshes || child_nodes.size()) {
- nodes.push_back(nd);
- }
- else {
- delete nd; /* bye, node */
- return;
- }
- }
- else {
-
- // Retain our current position in the hierarchy
- nodes.push_back(nd);
-
- // Now check for possible optimizations in our list of child nodes. join as many as possible
- aiNode* join_master = NULL;
- aiMatrix4x4 inv;
-
- const LockedSetType::const_iterator end = locked.end();
-
- std::list<aiNode*> join;
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) {
- aiNode* child = *it;
- if (child->mNumChildren == 0 && locked.find(AI_OG_GETKEY(child->mName)) == end) {
-
- // There may be no instanced meshes
- unsigned int n = 0;
- for (; n < child->mNumMeshes;++n) {
- if (meshes[child->mMeshes[n]] > 1) {
- break;
- }
- }
- if (n == child->mNumMeshes) {
-
- if (!join_master) {
- join_master = child;
- inv = join_master->mTransformation;
- inv.Inverse();
- }
- else {
-
- child->mTransformation = inv * child->mTransformation ;
-
- join.push_back(child);
- it = child_nodes.erase(it);
- continue;
- }
- }
- }
- ++it;
- }
- if (join_master && join.size()) {
- join_master->mName.length = sprintf(join_master->mName.data,"$MergedNode_%i",count_merged++);
-
- unsigned int out_meshes = 0;
- for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
- out_meshes += (*it)->mNumMeshes;
- }
-
- // copy all mesh references in one array
- if (out_meshes) {
- unsigned int* meshes = new unsigned int[out_meshes+join_master->mNumMeshes], *tmp = meshes;
- for (unsigned int n = 0; n < join_master->mNumMeshes;++n) {
- *tmp++ = join_master->mMeshes[n];
- }
-
- for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
- for (unsigned int n = 0; n < (*it)->mNumMeshes; ++n) {
-
- *tmp = (*it)->mMeshes[n];
- aiMesh* mesh = mScene->mMeshes[*tmp++];
-
- // manually move the mesh into the right coordinate system
- const aiMatrix3x3 IT = aiMatrix3x3( (*it)->mTransformation ).Inverse().Transpose();
- for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
-
- mesh->mVertices[a] *= (*it)->mTransformation;
-
- if (mesh->HasNormals())
- mesh->mNormals[a] *= IT;
-
- if (mesh->HasTangentsAndBitangents()) {
- mesh->mTangents[a] *= IT;
- mesh->mBitangents[a] *= IT;
- }
- }
- }
- delete *it; // bye, node
- }
- delete[] join_master->mMeshes;
- join_master->mMeshes = meshes;
- join_master->mNumMeshes += out_meshes;
- }
- }
- }
- // reassign children if something changed
- if (child_nodes.empty() || child_nodes.size() > nd->mNumChildren) {
-
- delete[] nd->mChildren;
-
- if (child_nodes.size())
- nd->mChildren = new aiNode*[child_nodes.size()];
- else nd->mChildren = NULL;
- }
-
- nd->mNumChildren = child_nodes.size();
-
- aiNode** tmp = nd->mChildren;
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
- aiNode* node = *tmp++ = *it;
- node->mParent = nd;
- }
-
- nodes_out += child_nodes.size();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Execute the postprocessing step on the given scene
-void OptimizeGraphProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("OptimizeGraphProcess begin");
- nodes_in = nodes_out = count_merged = 0;
- mScene = pScene;
-
- meshes.resize(pScene->mNumMeshes,0);
- FindInstancedMeshes(pScene->mRootNode);
-
- // build a blacklist of identifiers. If the name of a node matches one of these, we won't touch it
- locked.clear();
- for (std::list<std::string>::const_iterator it = locked_nodes.begin(); it != locked_nodes.end(); ++it) {
-#ifdef AI_OG_USE_HASHING
- locked.insert(SuperFastHash((*it).c_str()));
-#else
- locked.insert(*it);
-#endif
- }
-
- for (unsigned int i = 0; i < pScene->mNumAnimations; ++i) {
- for (unsigned int a = 0; a < pScene->mAnimations[i]->mNumChannels; ++a) {
-
- aiNodeAnim* anim = pScene->mAnimations[i]->mChannels[a];
- locked.insert(AI_OG_GETKEY(anim->mNodeName));
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- for (unsigned int a = 0; a < pScene->mMeshes[i]->mNumBones; ++a) {
-
- aiBone* bone = pScene->mMeshes[i]->mBones[a];
- locked.insert(AI_OG_GETKEY(bone->mName));
-
- // HACK: Meshes referencing bones may not be transformed; we need to look them.
- // The easiest way to do this is to increase their reference counters ...
- meshes[i] += 2;
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {
- aiCamera* cam = pScene->mCameras[i];
- locked.insert(AI_OG_GETKEY(cam->mName));
- }
-
- for (unsigned int i = 0; i < pScene->mNumLights; ++i) {
- aiLight* lgh = pScene->mLights[i];
- locked.insert(AI_OG_GETKEY(lgh->mName));
- }
-
- // Insert a dummy master node and make it read-only
- aiNode* dummy_root = new aiNode(AI_RESERVED_NODE_NAME);
- locked.insert(AI_OG_GETKEY(dummy_root->mName));
-
- const aiString prev = pScene->mRootNode->mName;
- pScene->mRootNode->mParent = dummy_root;
-
- dummy_root->mChildren = new aiNode*[dummy_root->mNumChildren = 1];
- dummy_root->mChildren[0] = pScene->mRootNode;
-
- // Do our recursive processing of scenegraph nodes. For each node collect
- // a fully new list of children and allow their children to place themselves
- // on the same hierarchy layer as their parents.
- std::list<aiNode*> nodes;
- CollectNewChildren (dummy_root,nodes);
-
- ai_assert(nodes.size() == 1);
-
- if (dummy_root->mNumChildren > 1) {
- pScene->mRootNode = dummy_root;
-
- // Keep the dummy node but assign the name of the old root node to it
- pScene->mRootNode->mName = prev;
- }
- else {
-
- // Remove the dummy root node again.
- pScene->mRootNode = dummy_root->mChildren[0];
-
- dummy_root->mChildren[0] = NULL;
- delete dummy_root;
- }
-
- pScene->mRootNode->mParent = NULL;
- if (!DefaultLogger::isNullLogger()) {
- if ( nodes_in != nodes_out) {
-
- char buf[512];
- sprintf(buf,"OptimizeGraphProcess finished; Input nodes: %i, Output nodes: %i",nodes_in,nodes_out);
- DefaultLogger::get()->info(buf);
- }
- else DefaultLogger::get()->debug("OptimizeGraphProcess finished");
- }
- meshes.clear();
- locked.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Buidl a LUT of all instanced meshes
-void OptimizeGraphProcess::FindInstancedMeshes (aiNode* pNode)
-{
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
- ++meshes[pNode->mMeshes[i]];
- }
-
- for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
- FindInstancedMeshes(pNode->mChildren[i]);
-}
-
-#endif // !! ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
diff --git a/3rdparty/assimp/code/OptimizeGraph.h b/3rdparty/assimp/code/OptimizeGraph.h
deleted file mode 100644
index 0572419e..00000000
--- a/3rdparty/assimp/code/OptimizeGraph.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file OptimizeGraph.h
- * @brief Declares a post processing step to optimize the scenegraph
- */
-#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
-#define AI_OPTIMIZEGRAPHPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
-#include "../include/aiTypes.h"
-
-struct aiMesh;
-class OptimizeGraphProcessTest;
-namespace Assimp {
-
-// -----------------------------------------------------------------------------
-/** @brief Postprocessing step to optimize the scenegraph
- *
- * The implementation tries to merge nodes, even if they use different
- * transformations. Animations are preserved.
- *
- * @see aiProcess_OptimizeGraph for a detailed description of the
- * algorithm being applied.
- */
-class ASSIMP_API OptimizeGraphProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::OptimizeGraphProcessTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- OptimizeGraphProcess();
-
- /** Destructor, private as well */
- ~OptimizeGraphProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Add a list of node names to be locked and not modified.
- * @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for
- * format explanations.
- */
- inline void AddLockedNodeList(std::string& in)
- {
- ConvertListToStrings (in,locked_nodes);
- }
-
- // -------------------------------------------------------------------
- /** @brief Add another node to be locked and not modified.
- * @param name Name to be locked
- */
- inline void AddLockedNode(std::string& name)
- {
- locked_nodes.push_back(name);
- }
-
- // -------------------------------------------------------------------
- /** @brief Rmeove a node from the list of locked nodes.
- * @param name Name to be unlocked
- */
- inline void RemoveLockedNode(std::string& name)
- {
- locked_nodes.remove(name);
- }
-
-protected:
-
- void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes);
- void FindInstancedMeshes (aiNode* pNode);
-
-private:
-
-#ifdef AI_OG_USE_HASHING
- typedef std::set<unsigned int> LockedSetType;
-#else
- typedef std::set<std::string> LockedSetType;
-#endif
-
-
- //! Scene we're working with
- aiScene* mScene;
-
- //! List of locked names. Stored is the hash of the name
- LockedSetType locked;
-
- //! List of nodes to be locked in addition to those with animations, lights or cameras assigned.
- std::list<std::string> locked_nodes;
-
- //! Node counters for logging purposes
- unsigned int nodes_in,nodes_out, count_merged;
-
- //! Reference counters for meshes
- std::vector<unsigned int> meshes;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_OPTIMIZEGRAPHPROCESS_H_INC
diff --git a/3rdparty/assimp/code/OptimizeMeshes.cpp b/3rdparty/assimp/code/OptimizeMeshes.cpp
deleted file mode 100644
index ca612739..00000000
--- a/3rdparty/assimp/code/OptimizeMeshes.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file OptimizeMeshes.cpp
- * @brief Implementation of the aiProcess_OptimizeMeshes step
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-
-using namespace Assimp;
-#include "OptimizeMeshes.h"
-#include "ProcessHelper.h"
-#include "SceneCombiner.h"
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OptimizeMeshesProcess::OptimizeMeshesProcess()
-: pts (false)
-, max_verts (0xffffffff)
-, max_faces (0xffffffff)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeMeshesProcess::~OptimizeMeshesProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
-{
- // Our behaviour needs to be different if the SortByPType or SplitLargeMeshes
- // steps are active. Thus we need to query their flags here and store the
- // information, although we're breaking const-correctness.
- // That's a serious design flaw, consider redesign.
- if ( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
- pts = (0 != (pFlags & aiProcess_SortByPType));
- max_verts = (0 != (pFlags & aiProcess_SplitLargeMeshes)) ? 0xdeadbeef : 0;
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the postprocessing step
-void OptimizeMeshesProcess::SetupProperties(const Importer* pImp)
-{
- if (max_verts == 0xdeadbeef /* magic hack */) {
- max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
- max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Execute step
-void OptimizeMeshesProcess::Execute( aiScene* pScene)
-{
- const unsigned int num_old = pScene->mNumMeshes;
- if (num_old <= 1) {
- DefaultLogger::get()->debug("Skipping OptimizeMeshesProcess");
- return;
- }
-
- DefaultLogger::get()->debug("OptimizeMeshesProcess begin");
- mScene = pScene;
-
- // need to clear persistent members from previous runs
- merge_list.clear();
- output.clear();
-
- merge_list.reserve(pScene->mNumMeshes);
- output.reserve(pScene->mNumMeshes);
-
- // Prepare lookup tables
- meshes.resize(pScene->mNumMeshes);
- FindInstancedMeshes(pScene->mRootNode);
- if (max_verts == 0xdeadbeef) /* undo the magic hack */
- max_verts = 0xffffffff;
-
- // ... instanced meshes are immediately processed and added to the output list
- for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) {
- meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]);
-
- if (meshes[i].instance_cnt > 1 && meshes[i].output_id == 0xffffffff) {
- meshes[i].output_id = n++;
- output.push_back(mScene->mMeshes[i]);
- }
- }
-
- // and process all nodes in the scenegraoh recursively
- ProcessNode(pScene->mRootNode);
- if (!output.size()) {
- throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong");
- }
-
- meshes.clear();
- ai_assert(output.size() <= num_old);
-
- mScene->mNumMeshes = output.size();
- std::copy(output.begin(),output.end(),mScene->mMeshes);
-
- if (output.size() != num_old) {
- char tmp[512];
- ::sprintf(tmp,"OptimizeMeshesProcess finished. Input meshes: %i, Output meshes: %i",num_old,pScene->mNumMeshes);
- DefaultLogger::get()->info(tmp);
- }
- else DefaultLogger::get()->debug("OptimizeMeshesProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Process meshes for a single node
-void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
-{
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
- unsigned int& im = pNode->mMeshes[i];
-
- if (meshes[im].instance_cnt > 1) {
- im = meshes[im].output_id;
- }
- else {
- merge_list.clear();
- unsigned int verts = 0, faces = 0;
-
- // Find meshes to merge with us
- for (unsigned int a = i+1; a < pNode->mNumMeshes;++a) {
- register unsigned int am = pNode->mMeshes[a];
- if (meshes[am].instance_cnt == 1 && CanJoin(im,am,verts,faces)) {
-
- merge_list.push_back(mScene->mMeshes[am]);
- verts += mScene->mMeshes[am]->mNumVertices;
- faces += mScene->mMeshes[am]->mNumFaces;
-
- --pNode->mNumMeshes;
- for (unsigned int n = a; n < pNode->mNumMeshes; ++n)
- pNode->mMeshes[n] = pNode->mMeshes[n+1];
-
- --a;
- }
- }
-
- // and merge all meshes which we found, replace the old ones
- if (!merge_list.empty()) {
- merge_list.push_back(mScene->mMeshes[im]);
-
- aiMesh* out;
- SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end());
- output.push_back(out);
- }
- else {
- output.push_back(mScene->mMeshes[im]);
- }
- im = output.size()-1;
- }
- }
-
-
- for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
- ProcessNode(pNode->mChildren[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether two meshes can be joined
-bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned int verts, unsigned int faces )
-{
- if (meshes[a].vertex_format != meshes[b].vertex_format)
- return false;
-
- aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b];
-
- if ((0xffffffff != max_verts && verts+mb->mNumVertices > max_verts) ||
- (0xffffffff != max_faces && faces+mb->mNumFaces > max_faces)) {
- return false;
- }
-
- // Never merge unskinned meshes with skinned meshes
- if (ma->mMaterialIndex != mb->mMaterialIndex || ma->HasBones() != mb->HasBones())
- return false;
-
- // Never merge meshes with different kinds of primitives if SortByPType did already
- // do its work. We would destroy everything again ...
- if (pts && ma->mPrimitiveTypes != mb->mPrimitiveTypes)
- return false;
-
- // If both meshes are skinned, check whether we have many bones defined in both meshes.
- // If yes, we can savely join them.
- if (ma->HasBones()) {
- // TODO
- return false;
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Buidl a LUT of all instanced meshes
-void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode)
-{
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
- ++meshes[pNode->mMeshes[i]].instance_cnt;
-
- for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
- FindInstancedMeshes(pNode->mChildren[i]);
-}
-
-#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
diff --git a/3rdparty/assimp/code/OptimizeMeshes.h b/3rdparty/assimp/code/OptimizeMeshes.h
deleted file mode 100644
index f7284ccc..00000000
--- a/3rdparty/assimp/code/OptimizeMeshes.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file OptimizeMeshes.h
- * @brief Declares a post processing step to join meshes, if possible
- */
-#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC
-#define AI_OPTIMIZEMESHESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiTypes.h"
-
-struct aiMesh;
-class OptimizeMeshesProcessTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @brief Postprocessing step to optimize mesh usage
- *
- * The implementation looks for meshes that could be joined and joins them.
- * Usually this will reduce the number of drawcalls.
- *
- * @note Instanced meshes are currently not processed.
- */
-class ASSIMP_API OptimizeMeshesProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::OptimizeMeshesProcessTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- OptimizeMeshesProcess();
-
- /** Destructor, private as well */
- ~OptimizeMeshesProcess();
-
-
- /** @brief Internal utility to store additional mesh info
- */
- struct MeshInfo
- {
- MeshInfo()
- : instance_cnt (0)
- , vertex_format (0)
- , output_id (0xffffffff)
- {}
-
- //! Number of times this mesh is referenced
- unsigned int instance_cnt;
-
- //! Vertex format id
- unsigned int vertex_format;
-
- //! Output ID
- unsigned int output_id;
- };
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Specify whether you want meshes with different
- * primitive types to be merged as well.
- *
- * IsActive() sets this property automatically to true if the
- * aiProcess_SortByPType flag is found.
- */
- void EnablePrimitiveTypeSorting(bool enable) {
- pts = enable;
- }
-
- // Getter
- bool IsPrimitiveTypeSortingEnabled () const {
- return pts;
- }
-
-
- // -------------------------------------------------------------------
- /** @brief Specify a maximum size of a single output mesh.
- *
- * If a single input mesh already exceeds this limit, it won't
- * be splitted.
- * @param verts Maximum number of vertices per mesh
- * @param faces Maximum number of faces per mesh
- */
- void SetPreferredMeshSizeLimit (unsigned int verts, unsigned int faces)
- {
- max_verts = verts;
- max_faces = faces;
- }
-
-
-protected:
-
- // -------------------------------------------------------------------
- /** @brief Do the actual optimization on all meshes of this node
- * @param pNode Node we're working with
- */
- void ProcessNode( aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** @brief Returns true if b can be joined with a
- *
- * @param verts Number of output verts up to now
- * @param faces Number of output faces up to now
- */
- bool CanJoin ( unsigned int a, unsigned int b,
- unsigned int verts, unsigned int faces );
-
- // -------------------------------------------------------------------
- /** @brief Find instanced meshes, for the moment we're excluding
- * them from all optimizations
- */
- void FindInstancedMeshes (aiNode* pNode);
-
-private:
-
- //! Scene we're working with
- aiScene* mScene;
-
- //! Per mesh info
- std::vector<MeshInfo> meshes;
-
- //! Next output mesh
- aiMesh* mesh;
-
- //! Output meshes
- std::vector<aiMesh*> output;
-
- //! @see EnablePrimitiveTypeSorting
- mutable bool pts;
-
- //! @see SetPreferredMeshSizeLimit
- mutable unsigned int max_verts,max_faces;
-
- //! Temporary storage
- std::vector<aiMesh*> merge_list;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/3rdparty/assimp/code/ParsingUtils.h b/3rdparty/assimp/code/ParsingUtils.h
deleted file mode 100644
index 4cae6519..00000000
--- a/3rdparty/assimp/code/ParsingUtils.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file ParsingUtils.h
- * @brief Defines helper functions for text parsing
- */
-#ifndef AI_PARSING_UTILS_H_INC
-#define AI_PARSING_UTILS_H_INC
-
-#include "StringComparison.h"
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsSpace( const char_t in)
-{
- return (in == (char_t)' ' || in == (char_t)'\t');
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsLineEnd( const char_t in)
-{
- return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsSpaceOrNewLine( const char_t in)
-{
- return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
-{
- while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
- *out = in;
- return !IsLineEnd<char_t>(*in);
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
-{
- return SkipSpaces<char_t>(*inout,inout);
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-inline bool SkipLine( const char_t* in, const char_t** out)
-{
- while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
-
- // files are opened in binary mode. Ergo there are both NL and CR
- while (*in == (char_t)'\r' || *in == (char_t)'\n')in++;
- *out = in;
- return *in != (char_t)'\0';
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-inline bool SkipLine( const char_t** inout)
-{
- return SkipLine<char_t>(*inout,inout);
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
-{
- while (*in == (char_t)' ' || *in == (char_t)'\t' ||
- *in == (char_t)'\r' || *in == (char_t)'\n')in++;
- *out = in;
- return *in != '\0';
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-inline bool SkipSpacesAndLineEnd( const char_t** inout)
-{
- return SkipSpacesAndLineEnd<char_t>(*inout,inout);
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-inline bool GetNextLine(const char_t*& buffer, char_t out[4096])
-{
- if ((char_t)'\0' == *buffer)return false;
-
- char* _out = out;
- char* const end = _out+4096;
- while (!IsLineEnd( *buffer ) && _out < end)
- *_out++ = *buffer++;
- *_out = (char_t)'\0';
-
- while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer;
- return true;
-}
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsNumeric( char_t in)
-{
- return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE bool TokenMatch(char*& in, const char* token, unsigned int len)
-{
- if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len]))
- {
- in += len+1;
- return true;
- }
- return false;
-}
-// ---------------------------------------------------------------------------------
-/** @brief Case-ignoring version of TokenMatch
- * @param in Input
- * @param token Token to check for
- * @param len Number of characters to check
- */
-AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len)
-{
- if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len]))
- {
- in += len+1;
- return true;
- }
- return false;
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE bool TokenMatch(const char*& in, const char* token, unsigned int len)
-{
- return TokenMatch(const_cast<char*&>(in), token, len);
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE void SkipToken(const char*& in)
-{
- SkipSpaces(&in);
- while (!IsSpaceOrNewLine(*in))++in;
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE std::string GetNextToken(const char*& in)
-{
- SkipSpacesAndLineEnd(&in);
- const char* cur = in;
- while (!IsSpaceOrNewLine(*in))++in;
- return std::string(cur,(size_t)(in-cur));
-}
-} // ! namespace Assimp
-#endif // ! AI_PARSING_UTILS_H_INC
diff --git a/3rdparty/assimp/code/PlyLoader.cpp b/3rdparty/assimp/code/PlyLoader.cpp
deleted file mode 100644
index f7f7d05c..00000000
--- a/3rdparty/assimp/code/PlyLoader.cpp
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file PlyLoader.cpp
- * @brief Implementation of the PLY importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-
-// internal headers
-#include "PlyLoader.h"
-#include "MaterialSystem.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-PLYImporter::PLYImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-PLYImporter::~PLYImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool PLYImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "ply")
- return true;
- else if (!extension.length() || checkSig)
- {
- if (!pIOHandler)return true;
- const char* tokens[] = {"ply"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void PLYImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ply");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void PLYImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open PLY file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- mBuffer = (unsigned char*)&mBuffer2[0];
-
- // the beginning of the file must be PLY - magic, magic
- if ((mBuffer[0] != 'P' && mBuffer[0] != 'p') ||
- (mBuffer[1] != 'L' && mBuffer[1] != 'l') ||
- (mBuffer[2] != 'Y' && mBuffer[2] != 'y')) {
- throw DeadlyImportError( "Invalid .ply file: Magic number \'ply\' is no there");
- }
-
- char* szMe = (char*)&this->mBuffer[3];
- SkipSpacesAndLineEnd(szMe,(const char**)&szMe);
-
- // determine the format of the file data
- PLY::DOM sPlyDom;
- if (TokenMatch(szMe,"format",6))
- {
- if (TokenMatch(szMe,"ascii",5))
- {
- SkipLine(szMe,(const char**)&szMe);
- if (!PLY::DOM::ParseInstance(szMe,&sPlyDom))
- throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#1)");
- }
- else if (!::strncmp(szMe,"binary_",7))
- {
- bool bIsBE = false;
- szMe+=7;
-
- // binary_little_endian
- // binary_big_endian
-#if (defined AI_BUILD_BIG_ENDIAN)
- if ('l' == *szMe || 'L' == *szMe)bIsBE = true;
-#else
- if ('b' == *szMe || 'B' == *szMe)bIsBE = true;
-#endif // ! AI_BUILD_BIG_ENDIAN
-
- // skip the line, parse the rest of the header and build the DOM
- SkipLine(szMe,(const char**)&szMe);
- if (!PLY::DOM::ParseInstanceBinary(szMe,&sPlyDom,bIsBE))
- throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#2)");
- }
- else throw DeadlyImportError( "Invalid .ply file: Unknown file format");
- }
- else
- {
- delete[] this->mBuffer;
- AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
- throw DeadlyImportError( "Invalid .ply file: Missing format specification");
- }
- this->pcDOM = &sPlyDom;
-
- // now load a list of vertices. This must be sucessfull in order to procede
- std::vector<aiVector3D> avPositions;
- this->LoadVertices(&avPositions,false);
-
- if (avPositions.empty())
- throw DeadlyImportError( "Invalid .ply file: No vertices found. "
- "Unable to parse the data format of the PLY file.");
-
- // now load a list of normals.
- std::vector<aiVector3D> avNormals;
- LoadVertices(&avNormals,true);
-
- // load the face list
- std::vector<PLY::Face> avFaces;
- LoadFaces(&avFaces);
-
- // if no face list is existing we assume that the vertex
- // list is containing a list of triangles
- if (avFaces.empty())
- {
- if (avPositions.size() < 3)
- {
- throw DeadlyImportError( "Invalid .ply file: Not enough "
- "vertices to build a proper face list. ");
- }
-
- const unsigned int iNum = (unsigned int)avPositions.size() / 3;
- for (unsigned int i = 0; i< iNum;++i)
- {
- PLY::Face sFace;
- sFace.mIndices.push_back((iNum*3));
- sFace.mIndices.push_back((iNum*3)+1);
- sFace.mIndices.push_back((iNum*3)+2);
- avFaces.push_back(sFace);
- }
- }
-
- // now load a list of all materials
- std::vector<MaterialHelper*> avMaterials;
- LoadMaterial(&avMaterials);
-
- // now load a list of all vertex color channels
- std::vector<aiColor4D> avColors;
- avColors.reserve(avPositions.size());
- LoadVertexColor(&avColors);
-
- // now try to load texture coordinates
- std::vector<aiVector2D> avTexCoords;
- avTexCoords.reserve(avPositions.size());
- LoadTextureCoordinates(&avTexCoords);
-
- // now replace the default material in all faces and validate all material indices
- ReplaceDefaultMaterial(&avFaces,&avMaterials);
-
- // now convert this to a list of aiMesh instances
- std::vector<aiMesh*> avMeshes;
- avMeshes.reserve(avMaterials.size()+1);
- ConvertMeshes(&avFaces,&avPositions,&avNormals,
- &avColors,&avTexCoords,&avMaterials,&avMeshes);
-
- if (avMeshes.empty())
- throw DeadlyImportError( "Invalid .ply file: Unable to extract mesh data ");
-
- // now generate the output scene object. Fill the material list
- pScene->mNumMaterials = (unsigned int)avMaterials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- pScene->mMaterials[i] = avMaterials[i];
-
- // fill the mesh list
- pScene->mNumMeshes = (unsigned int)avMeshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i] = avMeshes[i];
-
- // generate a simple node structure
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Split meshes by material IDs
-void PLYImporter::ConvertMeshes(std::vector<PLY::Face>* avFaces,
- const std::vector<aiVector3D>* avPositions,
- const std::vector<aiVector3D>* avNormals,
- const std::vector<aiColor4D>* avColors,
- const std::vector<aiVector2D>* avTexCoords,
- const std::vector<MaterialHelper*>* avMaterials,
- std::vector<aiMesh*>* avOut)
-{
- ai_assert(NULL != avFaces);
- ai_assert(NULL != avPositions);
- ai_assert(NULL != avMaterials);
-
- // split by materials
- std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[avMaterials->size()];
-
- unsigned int iNum = 0;
- for (std::vector<PLY::Face>::const_iterator i = avFaces->begin();i != avFaces->end();++i,++iNum)
- aiSplit[(*i).iMaterialIndex].push_back(iNum);
-
- // now generate submeshes
- for (unsigned int p = 0; p < avMaterials->size();++p)
- {
- if (aiSplit[p].size() != 0)
- {
- // allocate the mesh object
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mMaterialIndex = p;
-
- p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
- p_pcOut->mFaces = new aiFace[aiSplit[p].size()];
-
- // at first we need to determine the size of the output vector array
- unsigned int iNum = 0;
- for (unsigned int i = 0; i < aiSplit[p].size();++i)
- {
- iNum += (unsigned int)(*avFaces)[aiSplit[p][i]].mIndices.size();
- }
- p_pcOut->mNumVertices = iNum;
- p_pcOut->mVertices = new aiVector3D[iNum];
-
- if (!avColors->empty())
- p_pcOut->mColors[0] = new aiColor4D[iNum];
- if (!avTexCoords->empty())
- {
- p_pcOut->mNumUVComponents[0] = 2;
- p_pcOut->mTextureCoords[0] = new aiVector3D[iNum];
- }
- if (!avNormals->empty())
- p_pcOut->mNormals = new aiVector3D[iNum];
-
- // add all faces
- iNum = 0;
- unsigned int iVertex = 0;
- for (std::vector<unsigned int>::const_iterator i = aiSplit[p].begin();
- i != aiSplit[p].end();++i,++iNum)
- {
- p_pcOut->mFaces[iNum].mNumIndices = (unsigned int)(*avFaces)[*i].mIndices.size();
- p_pcOut->mFaces[iNum].mIndices = new unsigned int[p_pcOut->mFaces[iNum].mNumIndices];
-
- // build an unique set of vertices/colors for this face
- for (unsigned int q = 0; q < p_pcOut->mFaces[iNum].mNumIndices;++q)
- {
- p_pcOut->mFaces[iNum].mIndices[q] = iVertex;
- p_pcOut->mVertices[iVertex] = (*avPositions)[(*avFaces)[*i].mIndices[q]];
-
- if (!avColors->empty())
- p_pcOut->mColors[0][iVertex] = (*avColors)[(*avFaces)[*i].mIndices[q]];
-
- if (!avTexCoords->empty())
- {
- const aiVector2D& vec = (*avTexCoords)[(*avFaces)[*i].mIndices[q]];
- p_pcOut->mTextureCoords[0][iVertex].x = vec.x;
- p_pcOut->mTextureCoords[0][iVertex].y = vec.y;
- }
-
- if (!avNormals->empty())
- p_pcOut->mNormals[iVertex] = (*avNormals)[(*avFaces)[*i].mIndices[q]];
- iVertex++;
- }
-
- }
- // add the mesh to the output list
- avOut->push_back(p_pcOut);
- }
- }
- delete[] aiSplit; // cleanup
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate a default material if none was specified and apply it to all vanilla faces
-void PLYImporter::ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
- std::vector<MaterialHelper*>* avMaterials)
-{
- bool bNeedDefaultMat = false;
-
- for (std::vector<PLY::Face>::iterator i = avFaces->begin();i != avFaces->end();++i) {
- if (0xFFFFFFFF == (*i).iMaterialIndex) {
- bNeedDefaultMat = true;
- (*i).iMaterialIndex = (unsigned int)avMaterials->size();
- }
- else if ((*i).iMaterialIndex >= avMaterials->size() ) {
- // clamp the index
- (*i).iMaterialIndex = (unsigned int)avMaterials->size()-1;
- }
- }
-
- if (bNeedDefaultMat) {
- // generate a default material
- MaterialHelper* pcHelper = new MaterialHelper();
-
- // fill in a default material
- int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
-
- avMaterials->push_back(pcHelper);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- unsigned int aiPositions[2] = {0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[2] = {EDT_Char,EDT_Char};
- PLY::ElementInstanceList* pcList = NULL;
- unsigned int cnt = 0;
-
- // serach in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which normal components are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_UTextureCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_VTextureCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- }
- }
- }
- // check whether we have a valid source for the texture coordinates data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiVector2D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.x = PLY::PropertyInstance::ConvertTo<float>(
- (*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.y = PLY::PropertyInstance::ConvertTo<float>(
- (*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
- }
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract vertices from the PLY DOM
-void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
-{
- ai_assert(NULL != pvOut);
-
- unsigned int aiPositions[3] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[3] = {EDT_Char,EDT_Char,EDT_Char};
- PLY::ElementInstanceList* pcList = NULL;
- unsigned int cnt = 0;
-
- // serach in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &pcDOM->alElementData[_i];
-
- // load normal vectors?
- if (p_bNormals)
- {
- // now check whether which normal components are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_XNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_YNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_ZNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- }
- }
- // load vertex coordinates
- else
- {
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_XCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_YCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_ZCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- if (3 == cnt)break;
- }
- }
- break;
- }
- }
- // check whether we have a valid source for the vertex data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector<ElementInstance>::const_iterator
- i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiVector3D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.x = PLY::PropertyInstance::ConvertTo<float>(
- (*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.y = PLY::PropertyInstance::ConvertTo<float>(
- (*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
- }
-
- if (0xFFFFFFFF != aiPositions[2])
- {
- vOut.z = PLY::PropertyInstance::ConvertTo<float>(
- (*i).alProperties[aiPositions[2]].avList.front(),aiTypes[2]);
- }
-
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a color component to [0...1]
-float PLYImporter::NormalizeColorValue (PLY::PropertyInstance::ValueUnion val,
- PLY::EDataType eType)
-{
- switch (eType)
- {
- case EDT_Float:
- return val.fFloat;
- case EDT_Double:
- return (float)val.fDouble;
-
- case EDT_UChar:
- return (float)val.iUInt / (float)0xFF;
- case EDT_Char:
- return (float)(val.iInt+(0xFF/2)) / (float)0xFF;
- case EDT_UShort:
- return (float)val.iUInt / (float)0xFFFF;
- case EDT_Short:
- return (float)(val.iInt+(0xFFFF/2)) / (float)0xFFFF;
- case EDT_UInt:
- return (float)val.iUInt / (float)0xFFFF;
- case EDT_Int:
- return ((float)val.iInt / (float)0xFF) + 0.5f;
- default: ;
- };
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract proper vertex colors from the PLY DOM
-void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- unsigned int aiPositions[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[4] = {EDT_Char, EDT_Char, EDT_Char, EDT_Char}; // silencing gcc
- unsigned int cnt = 0;
- PLY::ElementInstanceList* pcList = NULL;
-
- // serach in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator
- a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_Red == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_Green == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_Blue == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- else if (PLY::EST_Alpha == (*a).Semantic)
- {
- cnt++;
- aiPositions[3] = _a;
- aiTypes[3] = (*a).eType;
- }
- if (4 == cnt)break;
- }
- break;
- }
- }
- // check whether we have a valid source for the vertex data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiColor4D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.r = NormalizeColorValue((*i).alProperties[
- aiPositions[0]].avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.g = NormalizeColorValue((*i).alProperties[
- aiPositions[1]].avList.front(),aiTypes[1]);
- }
-
- if (0xFFFFFFFF != aiPositions[2])
- {
- vOut.b = NormalizeColorValue((*i).alProperties[
- aiPositions[2]].avList.front(),aiTypes[2]);
- }
-
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
- else
- {
- vOut.a = NormalizeColorValue((*i).alProperties[
- aiPositions[3]].avList.front(),aiTypes[3]);
- }
-
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract proper faces from the PLY DOM
-void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- PLY::ElementInstanceList* pcList = NULL;
- bool bOne = false;
-
- // index of the vertex index list
- unsigned int iProperty = 0xFFFFFFFF;
- PLY::EDataType eType = EDT_Char;
- bool bIsTristrip = false;
-
- // index of the material index property
- unsigned int iMaterialIndex = 0xFFFFFFFF;
- PLY::EDataType eType2 = EDT_Char;
-
- // serach in the DOM for a face entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- // face = unique number of vertex indices
- if (PLY::EEST_Face == (*i).eSemantic)
- {
- pcList = &pcDOM->alElementData[_i];
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if (PLY::EST_VertexIndex == (*a).Semantic)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)continue;
- iProperty = _a;
- bOne = true;
- eType = (*a).eType;
- }
- else if (PLY::EST_MaterialIndex == (*a).Semantic)
- {
- if ((*a).bIsList)continue;
- iMaterialIndex = _a;
- bOne = true;
- eType2 = (*a).eType;
- }
- }
- break;
- }
- // triangle strip
- // TODO: triangle strip and material index support???
- else if (PLY::EEST_TriStrip == (*i).eSemantic)
- {
- // find a list property in this ...
- pcList = &this->pcDOM->alElementData[_i];
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)continue;
- iProperty = _a;
- bOne = true;
- bIsTristrip = true;
- eType = (*a).eType;
- break;
- }
- break;
- }
- }
- // check whether we have at least one per-face information set
- if (pcList && bOne)
- {
- if (!bIsTristrip)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- PLY::Face sFace;
-
- // parse the list of vertex indices
- if (0xFFFFFFFF != iProperty)
- {
- const unsigned int iNum = (unsigned int)(*i).alProperties[iProperty].avList.size();
- sFace.mIndices.resize(iNum);
-
- std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
- (*i).alProperties[iProperty].avList.begin();
-
- for (unsigned int a = 0; a < iNum;++a,++p)
- {
- sFace.mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p,eType);
- }
- }
-
- // parse the material index
- if (0xFFFFFFFF != iMaterialIndex)
- {
- sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
- (*i).alProperties[iMaterialIndex].avList.front(),eType2);
- }
- pvOut->push_back(sFace);
- }
- }
- else // triangle strips
- {
- // normally we have only one triangle strip instance where
- // a value of -1 indicates a restart of the strip
- bool flip = false;
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
- const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
- pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
-
- int aiTable[2] = {-1,-1};
- for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin();a != quak.end();++a) {
- const int p = PLY::PropertyInstance::ConvertTo<int>(*a,eType);
-
- if (-1 == p) {
- // restart the strip ...
- aiTable[0] = aiTable[1] = -1;
- flip = false;
- continue;
- }
- if (-1 == aiTable[0]) {
- aiTable[0] = p;
- continue;
- }
- if (-1 == aiTable[1]) {
- aiTable[1] = p;
- continue;
- }
-
- pvOut->push_back(PLY::Face());
- PLY::Face& sFace = pvOut->back();
- sFace.mIndices[0] = aiTable[0];
- sFace.mIndices[1] = aiTable[1];
- sFace.mIndices[2] = p;
- if ((flip = !flip)) {
- std::swap(sFace.mIndices[0],sFace.mIndices[1]);
- }
-
- aiTable[0] = aiTable[1];
- aiTable[1] = p;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a RGBA color in [0...1] range
-void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avList,
- unsigned int aiPositions[4],
- PLY::EDataType aiTypes[4],
- aiColor4D* clrOut)
-{
- ai_assert(NULL != clrOut);
-
- if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
- else
- {
- clrOut->r = NormalizeColorValue(avList[
- aiPositions[0]].avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
- else
- {
- clrOut->g = NormalizeColorValue(avList[
- aiPositions[1]].avList.front(),aiTypes[1]);
- }
-
- if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
- else
- {
- clrOut->b = NormalizeColorValue(avList[
- aiPositions[2]].avList.front(),aiTypes[2]);
- }
-
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
- else
- {
- clrOut->a = NormalizeColorValue(avList[
- aiPositions[3]].avList.front(),aiTypes[3]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract a material from the PLY DOM
-void PLYImporter::LoadMaterial(std::vector<MaterialHelper*>* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- // diffuse[4], specular[4], ambient[4]
- // rgba order
- unsigned int aaiPositions[3][4] = {
-
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- };
-
- PLY::EDataType aaiTypes[3][4] = {
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char},
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char},
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char}
- };
- PLY::ElementInstanceList* pcList = NULL;
-
- unsigned int iPhong = 0xFFFFFFFF;
- PLY::EDataType ePhong = EDT_Char;
-
- unsigned int iOpacity = 0xFFFFFFFF;
- PLY::EDataType eOpacity = EDT_Char;
-
- // serach in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
- i != this->pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Material == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator
- a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
-
- // pohng specularity -----------------------------------
- if (PLY::EST_PhongPower == (*a).Semantic)
- {
- iPhong = _a;
- ePhong = (*a).eType;
- }
-
- // general opacity -----------------------------------
- if (PLY::EST_Opacity == (*a).Semantic)
- {
- iOpacity = _a;
- eOpacity = (*a).eType;
- }
-
- // diffuse color channels -----------------------------------
- if (PLY::EST_DiffuseRed == (*a).Semantic)
- {
- aaiPositions[0][0] = _a;
- aaiTypes[0][0] = (*a).eType;
- }
- else if (PLY::EST_DiffuseGreen == (*a).Semantic)
- {
- aaiPositions[0][1] = _a;
- aaiTypes[0][1] = (*a).eType;
- }
- else if (PLY::EST_DiffuseBlue == (*a).Semantic)
- {
- aaiPositions[0][2] = _a;
- aaiTypes[0][2] = (*a).eType;
- }
- else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
- {
- aaiPositions[0][3] = _a;
- aaiTypes[0][3] = (*a).eType;
- }
- // specular color channels -----------------------------------
- else if (PLY::EST_SpecularRed == (*a).Semantic)
- {
- aaiPositions[1][0] = _a;
- aaiTypes[1][0] = (*a).eType;
- }
- else if (PLY::EST_SpecularGreen == (*a).Semantic)
- {
- aaiPositions[1][1] = _a;
- aaiTypes[1][1] = (*a).eType;
- }
- else if (PLY::EST_SpecularBlue == (*a).Semantic)
- {
- aaiPositions[1][2] = _a;
- aaiTypes[1][2] = (*a).eType;
- }
- else if (PLY::EST_SpecularAlpha == (*a).Semantic)
- {
- aaiPositions[1][3] = _a;
- aaiTypes[1][3] = (*a).eType;
- }
- // ambient color channels -----------------------------------
- else if (PLY::EST_AmbientRed == (*a).Semantic)
- {
- aaiPositions[2][0] = _a;
- aaiTypes[2][0] = (*a).eType;
- }
- else if (PLY::EST_AmbientGreen == (*a).Semantic)
- {
- aaiPositions[2][1] = _a;
- aaiTypes[2][1] = (*a).eType;
- }
- else if (PLY::EST_AmbientBlue == (*a).Semantic)
- {
- aaiPositions[2][2] = _a;
- aaiTypes[2][2] = (*a).eType;
- }
- else if (PLY::EST_AmbientAlpha == (*a).Semantic)
- {
- aaiPositions[2][3] = _a;
- aaiTypes[2][3] = (*a).eType;
- }
- }
- break;
- }
- }
- // check whether we have a valid source for the material data
- if (NULL != pcList) {
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
- aiColor4D clrOut;
- MaterialHelper* pcHelper = new MaterialHelper();
-
- // build the diffuse material color
- GetMaterialColor((*i).alProperties,aaiPositions[0],aaiTypes[0],&clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // build the specular material color
- GetMaterialColor((*i).alProperties,aaiPositions[1],aaiTypes[1],&clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_SPECULAR);
-
- // build the ambient material color
- GetMaterialColor((*i).alProperties,aaiPositions[2],aaiTypes[2],&clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut,1,AI_MATKEY_COLOR_AMBIENT);
-
- // handle phong power and shading mode
- int iMode;
- if (0xFFFFFFFF != iPhong) {
- float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong);
-
- // if shininess is 0 (and the pow() calculation would therefore always
- // become 1, not depending on the angle), use gouraud lighting
- if (fSpec) {
- // scale this with 15 ... hopefully this is correct
- fSpec *= 15;
- pcHelper->AddProperty<float>(&fSpec, 1, AI_MATKEY_SHININESS);
-
- iMode = (int)aiShadingMode_Phong;
- }
- else iMode = (int)aiShadingMode_Gouraud;
- }
- else iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // handle opacity
- if (0xFFFFFFFF != iOpacity) {
- float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity);
- pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
- }
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
-
- // add the newly created material instance to the list
- pvOut->push_back(pcHelper);
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/3rdparty/assimp/code/PlyLoader.h b/3rdparty/assimp/code/PlyLoader.h
deleted file mode 100644
index 814321d7..00000000
--- a/3rdparty/assimp/code/PlyLoader.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file PLYLoader.h
- * @brief Declaration of the .ply importer class.
- */
-#ifndef AI_PLYLOADER_H_INCLUDED
-#define AI_PLYLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-struct aiNode;
-
-#include "PlyParser.h"
-
-namespace Assimp {
-class MaterialHelper;
-
-using namespace PLY;
-
-// ---------------------------------------------------------------------------
-/** Importer class to load the stanford PLY file format
-*/
-class PLYImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- PLYImporter();
-
- /** Destructor, private as well */
- ~PLYImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Extract vertices from the DOM
- */
- void LoadVertices(std::vector<aiVector3D>* pvOut,
- bool p_bNormals = false);
-
- // -------------------------------------------------------------------
- /** Extract vertex color channels from the DOM
- */
- void LoadVertexColor(std::vector<aiColor4D>* pvOut);
-
- // -------------------------------------------------------------------
- /** Extract texture coordinate channels from the DOM
- */
- void LoadTextureCoordinates(std::vector<aiVector2D>* pvOut);
-
- // -------------------------------------------------------------------
- /** Extract a face list from the DOM
- */
- void LoadFaces(std::vector<PLY::Face>* pvOut);
-
- // -------------------------------------------------------------------
- /** Extract a material list from the DOM
- */
- void LoadMaterial(std::vector<MaterialHelper*>* pvOut);
-
-
- // -------------------------------------------------------------------
- /** Validate material indices, replace default material identifiers
- */
- void ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
- std::vector<MaterialHelper*>* avMaterials);
-
-
- // -------------------------------------------------------------------
- /** Convert all meshes into our ourer representation
- */
- void ConvertMeshes(std::vector<PLY::Face>* avFaces,
- const std::vector<aiVector3D>* avPositions,
- const std::vector<aiVector3D>* avNormals,
- const std::vector<aiColor4D>* avColors,
- const std::vector<aiVector2D>* avTexCoords,
- const std::vector<MaterialHelper*>* avMaterials,
- std::vector<aiMesh*>* avOut);
-
-
- // -------------------------------------------------------------------
- /** Static helper to parse a color from four single channels in
- */
- static void GetMaterialColor(
- const std::vector<PLY::PropertyInstance>& avList,
- unsigned int aiPositions[4],
- PLY::EDataType aiTypes[4],
- aiColor4D* clrOut);
-
-
- // -------------------------------------------------------------------
- /** Static helper to parse a color channel value. The input value
- * is normalized to 0-1.
- */
- static float NormalizeColorValue (
- PLY::PropertyInstance::ValueUnion val,
- PLY::EDataType eType);
-
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** Document object model representation extracted from the file */
- PLY::DOM* pcDOM;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/PlyParser.cpp b/3rdparty/assimp/code/PlyParser.cpp
deleted file mode 100644
index d0e3fa0f..00000000
--- a/3rdparty/assimp/code/PlyParser.cpp
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the PLY parser class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-
-#include "PlyLoader.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-PLY::EDataType PLY::Property::ParseDataType(const char* pCur,const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
- PLY::EDataType eOut = PLY::EDT_INVALID;
-
- if (TokenMatch(pCur,"char",4) ||
- TokenMatch(pCur,"int8",4))
- {
- eOut = PLY::EDT_Char;
- }
- else if (TokenMatch(pCur,"uchar",5) ||
- TokenMatch(pCur,"uint8",5))
- {
- eOut = PLY::EDT_UChar;
- }
- else if (TokenMatch(pCur,"short",5) ||
- TokenMatch(pCur,"int16",5))
- {
- eOut = PLY::EDT_Short;
- }
- else if (TokenMatch(pCur,"ushort",6) ||
- TokenMatch(pCur,"uint16",6))
- {
- eOut = PLY::EDT_UShort;
- }
- else if (TokenMatch(pCur,"int32",5) || TokenMatch(pCur,"int",3))
- {
- eOut = PLY::EDT_Int;
- }
- else if (TokenMatch(pCur,"uint32",6) || TokenMatch(pCur,"uint",4))
- {
- eOut = PLY::EDT_UInt;
- }
- else if (TokenMatch(pCur,"float",5) || TokenMatch(pCur,"float32",7))
- {
- eOut = PLY::EDT_Float;
- }
- else if (TokenMatch(pCur,"double64",8) || TokenMatch(pCur,"double",6) ||
- TokenMatch(pCur,"float64",7))
- {
- eOut = PLY::EDT_Double;
- }
- if (PLY::EDT_INVALID == eOut)
- {
- DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
- }
- *pCurOut = pCur;
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::ESemantic PLY::Property::ParseSemantic(const char* pCur,const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
-
- PLY::ESemantic eOut = PLY::EST_INVALID;
- if (TokenMatch(pCur,"red",3))
- {
- eOut = PLY::EST_Red;
- }
- else if (TokenMatch(pCur,"green",5))
- {
- eOut = PLY::EST_Green;
- }
- else if (TokenMatch(pCur,"blue",4))
- {
- eOut = PLY::EST_Blue;
- }
- else if (TokenMatch(pCur,"alpha",5))
- {
- eOut = PLY::EST_Alpha;
- }
- else if (TokenMatch(pCur,"vertex_index",12) || TokenMatch(pCur,"vertex_indices",14))
- {
- eOut = PLY::EST_VertexIndex;
- }
- else if (TokenMatch(pCur,"material_index",14))
- {
- eOut = PLY::EST_MaterialIndex;
- }
- else if (TokenMatch(pCur,"ambient_red",11))
- {
- eOut = PLY::EST_AmbientRed;
- }
- else if (TokenMatch(pCur,"ambient_green",13))
- {
- eOut = PLY::EST_AmbientGreen;
- }
- else if (TokenMatch(pCur,"ambient_blue",12))
- {
- eOut = PLY::EST_AmbientBlue;
- }
- else if (TokenMatch(pCur,"ambient_alpha",13))
- {
- eOut = PLY::EST_AmbientAlpha;
- }
- else if (TokenMatch(pCur,"diffuse_red",11))
- {
- eOut = PLY::EST_DiffuseRed;
- }
- else if (TokenMatch(pCur,"diffuse_green",13))
- {
- eOut = PLY::EST_DiffuseGreen;
- }
- else if (TokenMatch(pCur,"diffuse_blue",12))
- {
- eOut = PLY::EST_DiffuseBlue;
- }
- else if (TokenMatch(pCur,"diffuse_alpha",13))
- {
- eOut = PLY::EST_DiffuseAlpha;
- }
- else if (TokenMatch(pCur,"specular_red",12))
- {
- eOut = PLY::EST_SpecularRed;
- }
- else if (TokenMatch(pCur,"specular_green",14))
- {
- eOut = PLY::EST_SpecularGreen;
- }
- else if (TokenMatch(pCur,"specular_blue",13))
- {
- eOut = PLY::EST_SpecularBlue;
- }
- else if (TokenMatch(pCur,"specular_alpha",14))
- {
- eOut = PLY::EST_SpecularAlpha;
- }
- else if (TokenMatch(pCur,"opacity",7))
- {
- eOut = PLY::EST_Opacity;
- }
- else if (TokenMatch(pCur,"specular_power",6))
- {
- eOut = PLY::EST_PhongPower;
- }
- else if (TokenMatch(pCur,"r",1))
- {
- eOut = PLY::EST_Red;
- }
- else if (TokenMatch(pCur,"g",1))
- {
- eOut = PLY::EST_Green;
- }
- else if (TokenMatch(pCur,"b",1))
- {
- eOut = PLY::EST_Blue;
- }
- // NOTE: Blender3D exports texture coordinates as s,t tuples
- else if (TokenMatch(pCur,"u",1) || TokenMatch(pCur,"s",1) || TokenMatch(pCur,"tx",2))
- {
- eOut = PLY::EST_UTextureCoord;
- }
- else if (TokenMatch(pCur,"v",1) || TokenMatch(pCur,"t",1) || TokenMatch(pCur,"ty",2))
- {
- eOut = PLY::EST_VTextureCoord;
- }
- else if (TokenMatch(pCur,"x",1))
- {
- eOut = PLY::EST_XCoord;
- }
- else if (TokenMatch(pCur,"y",1))
- {
- eOut = PLY::EST_YCoord;
- }
- else if (TokenMatch(pCur,"z",1))
- {
- eOut = PLY::EST_ZCoord;
- }
- else if (TokenMatch(pCur,"nx",2))
- {
- eOut = PLY::EST_XNormal;
- }
- else if (TokenMatch(pCur,"ny",2))
- {
- eOut = PLY::EST_YNormal;
- }
- else if (TokenMatch(pCur,"nz",2))
- {
- eOut = PLY::EST_ZNormal;
- }
- else
- {
- DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
- SkipLine(&pCur);
- }
- *pCurOut = pCur;
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::Property::ParseProperty (const char* pCur,
- const char** pCurOut,
- PLY::Property* pOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
-
- // Forms supported:
- // "property float x"
- // "property list uchar int vertex_index"
- *pCurOut = pCur;
-
- // skip leading spaces
- if (!SkipSpaces(pCur,&pCur))return false;
-
- // skip the "property" string at the beginning
- if (!TokenMatch(pCur,"property",8))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!SkipSpaces(pCur,&pCur))return false;
- if (TokenMatch(pCur,"list",4))
- {
- pOut->bIsList = true;
-
- // seems to be a list.
- if (EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse list size data type
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- if (!SkipSpaces(pCur,&pCur))return false;
- if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse list data type
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- }
- else
- {
- if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse data type. Skip the property
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- }
-
- if (!SkipSpaces(pCur,&pCur))return false;
- const char* szCur = pCur;
- pOut->Semantic = PLY::Property::ParseSemantic(pCur, &pCur);
-
- if (PLY::EST_INVALID == pOut->Semantic)
- {
- // store the name of the semantic
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
-
- DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
- pOut->szName = std::string(szCur,iDiff);
- }
-
- SkipSpacesAndLineEnd(pCur,&pCur);
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::EElementSemantic PLY::Element::ParseSemantic(const char* pCur,
- const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
- PLY::EElementSemantic eOut = PLY::EEST_INVALID;
- if (TokenMatch(pCur,"vertex",6))
- {
- eOut = PLY::EEST_Vertex;
- }
- else if (TokenMatch(pCur,"face",4))
- {
- eOut = PLY::EEST_Face;
- }
-#if 0
- // TODO: maybe implement this?
- else if (TokenMatch(pCur,"range_grid",10))
- {
- eOut = PLY::EEST_Face;
- }
-#endif
- else if (TokenMatch(pCur,"tristrips",9))
- {
- eOut = PLY::EEST_TriStrip;
- }
- else if (TokenMatch(pCur,"edge",4))
- {
- eOut = PLY::EEST_Edge;
- }
- else if (TokenMatch(pCur,"material",8))
- {
- eOut = PLY::EEST_Material;
- }
- *pCurOut = pCur;
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::Element::ParseElement (const char* pCur,
- const char** pCurOut,
- PLY::Element* pOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != pOut);
-
- // Example format: "element vertex 8"
- *pCurOut = pCur;
-
- // skip leading spaces
- if (!SkipSpaces(&pCur))return false;
-
- // skip the "element" string at the beginning
- if (!TokenMatch(pCur,"element",7))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!SkipSpaces(&pCur))return false;
-
- // parse the semantic of the element
- const char* szCur = pCur;
- pOut->eSemantic = PLY::Element::ParseSemantic(pCur,&pCur);
- if (PLY::EEST_INVALID == pOut->eSemantic)
- {
- // if the exact semantic can't be determined, just store
- // the original string identifier
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- pOut->szName = std::string(szCur,iDiff);
- }
-
- if (!SkipSpaces(&pCur))return false;
-
- //parse the number of occurences of this element
- pOut->NumOccur = strtol10(pCur,&pCur);
-
- // go to the next line
- SkipSpacesAndLineEnd(pCur,&pCur);
-
- // now parse all properties of the element
- while (true)
- {
- // skip all comments
- PLY::DOM::SkipComments(pCur,&pCur);
-
- PLY::Property prop;
- if (!PLY::Property::ParseProperty(pCur,&pCur,&prop))break;
- pOut->alProperties.push_back(prop);
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::SkipComments (const char* pCur,
- const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
- *pCurOut = pCur;
-
- // skip spaces
- if (!SkipSpaces(pCur,&pCur))return false;
-
- if (TokenMatch(pCur,"comment",7))
- {
- SkipLine(pCur,&pCur);
- SkipComments(pCur,&pCur);
- *pCurOut = pCur;
- return true;
- }
- *pCurOut = pCur;
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
-
- // after ply and format line
- *pCurOut = pCur;
-
- // parse all elements
- while (true)
- {
- // skip all comments
- PLY::DOM::SkipComments(pCur,&pCur);
-
- PLY::Element out;
- if (PLY::Element::ParseElement(pCur,&pCur,&out))
- {
- // add the element to the list of elements
- alElements.push_back(out);
- }
- else if (TokenMatch(pCur,"end_header",10))
- {
- // we have reached the end of the header
- break;
- }
- else
- {
- // ignore unknown header elements
- SkipLine(&pCur);
- }
- }
- SkipSpacesAndLineEnd(pCur,&pCur);
- *pCurOut = pCur;
-
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceLists (
- const char* pCur,
- const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
- *pCurOut = pCur;
-
- alElementData.resize(alElements.size());
-
- std::vector<PLY::Element>::const_iterator i = alElements.begin();
- std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
-
- // parse all element instances
- for (;i != alElements.end();++i,++a)
- {
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceList(pCur,&pCur,&(*i),&(*a));
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceListsBinary (
- const char* pCur,
- const char** pCurOut,
- bool p_bBE)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
- *pCurOut = pCur;
-
- alElementData.resize(alElements.size());
-
- std::vector<PLY::Element>::const_iterator i = alElements.begin();
- std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
-
- // parse all element instances
- for (;i != alElements.end();++i,++a)
- {
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceListBinary(pCur,&pCur,&(*i),&(*a),p_bBE);
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE)
-{
- ai_assert(NULL != pCur && NULL != p_pcOut);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
-
- if (!p_pcOut->ParseHeader(pCur,&pCur))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
- if (!p_pcOut->ParseElementInstanceListsBinary(pCur,&pCur,p_bBE))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut)
-{
- ai_assert(NULL != pCur);
- ai_assert(NULL != p_pcOut);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
-
-
- if (!p_pcOut->ParseHeader(pCur,&pCur))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
- if (!p_pcOut->ParseElementInstanceLists(pCur,&pCur))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceList (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
-
- if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
- {
- // if the element has an unknown semantic we can skip all lines
- // However, there could be comments
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::DOM::SkipComments(pCur,&pCur);
- SkipLine(pCur,&pCur);
- }
- }
- else
- {
- // be sure to have enough storage
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::DOM::SkipComments(pCur,&pCur);
- PLY::ElementInstance::ParseInstance(pCur, &pCur,pcElement,
- &p_pcOut->alInstances[i]);
- }
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceListBinary (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut,
- bool p_bBE /* = false */)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
-
- // we can add special handling code for unknown element semantics since
- // we can't skip it as a whole block (we don't know its exact size
- // due to the fact that lists could be contained in the property list
- // of the unknown element)
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::ElementInstance::ParseInstanceBinary(pCur, &pCur,pcElement,
- &p_pcOut->alInstances[i], p_bBE);
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstance (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
-
- if (!SkipSpaces(pCur, &pCur))return false;
-
- // allocate enough storage
- p_pcOut->alProperties.resize(pcElement->alProperties.size());
-
- std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
- std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- for (;i != p_pcOut->alProperties.end();++i,++a)
- {
- if (!(PLY::PropertyInstance::ParseInstance(pCur, &pCur,&(*a),&(*i))))
- {
- DefaultLogger::get()->warn("Unable to parse property instance. "
- "Skipping this element instance");
-
- // skip the rest of the instance
- SkipLine(pCur, &pCur);
-
- PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
- (*i).avList.push_back(v);
- }
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstanceBinary (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut,
- bool p_bBE /* = false */)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
-
- // allocate enough storage
- p_pcOut->alProperties.resize(pcElement->alProperties.size());
-
- std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
- std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- for (;i != p_pcOut->alProperties.end();++i,++a)
- {
- if (!(PLY::PropertyInstance::ParseInstanceBinary(pCur, &pCur,&(*a),&(*i),p_bBE)))
- {
- DefaultLogger::get()->warn("Unable to parse binary property instance. "
- "Skipping this element instance");
-
- (*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType));
- }
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseInstance (const char* pCur,const char** pCurOut,
- const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut);
-
- *pCurOut = pCur;
-
- // skip spaces at the beginning
- if (!SkipSpaces(pCur, &pCur))return false;
-
- if (prop->bIsList)
- {
- // parse the number of elements in the list
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eFirstType,&v);
-
- // convert to unsigned int
- unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
-
- // parse all list elements
- p_pcOut->avList.resize(iNum);
- for (unsigned int i = 0; i < iNum;++i)
- {
- if (!SkipSpaces(pCur, &pCur))return false;
- PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&p_pcOut->avList[i]);
- }
- }
- else
- {
- // parse the property
- PLY::PropertyInstance::ValueUnion v;
-
- PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&v);
- p_pcOut->avList.push_back(v);
- }
- SkipSpacesAndLineEnd(pCur, &pCur);
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseInstanceBinary (
- const char* pCur,
- const char** pCurOut,
- const PLY::Property* prop,
- PLY::PropertyInstance* p_pcOut,
- bool p_bBE)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut);
-
- if (prop->bIsList)
- {
- // parse the number of elements in the list
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eFirstType,&v,p_bBE);
-
- // convert to unsigned int
- unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
-
- // parse all list elements
- p_pcOut->avList.resize(iNum);
- for (unsigned int i = 0; i < iNum;++i){
- PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&p_pcOut->avList[i],p_bBE);
- }
- }
- else
- {
- // parse the property
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&v,p_bBE);
- p_pcOut->avList.push_back(v);
- }
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(
- PLY::EDataType eType)
-{
- PLY::PropertyInstance::ValueUnion out;
-
- switch (eType)
- {
- case EDT_Float:
- out.fFloat = 0.f;
- return out;
-
- case EDT_Double:
- out.fDouble = 0.;
- return out;
-
- default: ;
- };
- out.iUInt = 0;
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseValue(
- const char* pCur,
- const char** pCurOut,
- PLY::EDataType eType,
- PLY::PropertyInstance::ValueUnion* out)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
-
- register bool ret = true;
- *pCurOut = pCur;
- switch (eType)
- {
- case EDT_UInt:
- case EDT_UShort:
- case EDT_UChar:
-
- out->iUInt = (uint32_t)strtol10(pCur, &pCur);
- break;
-
- case EDT_Int:
- case EDT_Short:
- case EDT_Char:
-
- out->iInt = (int32_t)strtol10s(pCur, &pCur);
- break;
-
- case EDT_Float:
-
- pCur = fast_atof_move(pCur,out->fFloat);
- break;
-
- case EDT_Double:
-
- float f;
- pCur = fast_atof_move(pCur,f);
- out->fDouble = (double)f;
- break;
-
- default:
- ret = false;
- }
- *pCurOut = pCur;
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseValueBinary(
- const char* pCur,
- const char** pCurOut,
- PLY::EDataType eType,
- PLY::PropertyInstance::ValueUnion* out,
- bool p_bBE)
-{
- ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
-
- register bool ret = true;
- switch (eType)
- {
- case EDT_UInt:
- out->iUInt = (uint32_t)*((uint32_t*)pCur);
- pCur += 4;
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt);
- break;
-
- case EDT_UShort:
- {
- int16_t i = *((uint16_t*)pCur);
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap(&i);
- out->iUInt = (uint32_t)i;
- pCur += 2;
- break;
- }
-
- case EDT_UChar:
- {
- out->iUInt = (uint32_t)(*((uint8_t*)pCur));
- pCur ++;
- break;
- }
-
- case EDT_Int:
- out->iInt = *((int32_t*)pCur);
- pCur += 4;
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap(&out->iInt);
- break;
-
- case EDT_Short:
- {
- int16_t i = *((int16_t*)pCur);
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap(&i);
- out->iInt = (int32_t)i;
- pCur += 2;
- break;
- }
-
- case EDT_Char:
- out->iInt = (int32_t)*((int8_t*)pCur);
- pCur ++;
- break;
-
- case EDT_Float:
- {
- out->fFloat = *((float*)pCur);
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat);
- pCur += 4;
- break;
- }
- case EDT_Double:
- {
- out->fDouble = *((double*)pCur);
-
- // Swap endianess
- if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble);
- pCur += 8;
- break;
- }
- default:
- ret = false;
- }
- *pCurOut = pCur;
- return ret;
-}
-
-#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/3rdparty/assimp/code/PlyParser.h b/3rdparty/assimp/code/PlyParser.h
deleted file mode 100644
index 379ea4a0..00000000
--- a/3rdparty/assimp/code/PlyParser.h
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines the helper data structures for importing PLY files */
-#ifndef AI_PLYFILEHELPER_H_INC
-#define AI_PLYFILEHELPER_H_INC
-
-
-#include "ParsingUtils.h"
-
-
-namespace Assimp
-{
-
-// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
-// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
-// http://www.okino.com/conv/exp_ply.htm
-namespace PLY
-{
-
-
-// ---------------------------------------------------------------------------------
-/*
-name type number of bytes
----------------------------------------
-char character 1
-uchar unsigned character 1
-short short integer 2
-ushort unsigned short integer 2
-int integer 4
-uint unsigned integer 4
-float single-precision float 4
-double double-precision float 8
-
-int8
-int16
-uint8 ... forms are also used
-*/
-enum EDataType
-{
- EDT_Char = 0x0u,
- EDT_UChar,
- EDT_Short,
- EDT_UShort,
- EDT_Int,
- EDT_UInt,
- EDT_Float,
- EDT_Double,
-
- // Marks invalid entries
- EDT_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Specifies semantics for PLY element properties
- *
- * Semantics define the usage of a property, e.g. x coordinate
-*/
-enum ESemantic
-{
- //! vertex position x coordinate
- EST_XCoord = 0x0u,
- //! vertex position x coordinate
- EST_YCoord,
- //! vertex position x coordinate
- EST_ZCoord,
-
- //! vertex normal x coordinate
- EST_XNormal,
- //! vertex normal y coordinate
- EST_YNormal,
- //! vertex normal z coordinate
- EST_ZNormal,
-
- //! u texture coordinate
- EST_UTextureCoord,
- //! v texture coordinate
- EST_VTextureCoord,
-
- //! vertex colors, red channel
- EST_Red,
- //! vertex colors, green channel
- EST_Green,
- //! vertex colors, blue channel
- EST_Blue,
- //! vertex colors, alpha channel
- EST_Alpha,
-
- //! vertex index list
- EST_VertexIndex,
-
- //! texture index
- EST_TextureIndex,
-
- //! texture coordinates (stored as element of a face)
- EST_TextureCoordinates,
-
- //! material index
- EST_MaterialIndex,
-
- //! ambient color, red channel
- EST_AmbientRed,
- //! ambient color, green channel
- EST_AmbientGreen,
- //! ambient color, blue channel
- EST_AmbientBlue,
- //! ambient color, alpha channel
- EST_AmbientAlpha,
-
- //! diffuse color, red channel
- EST_DiffuseRed,
- //! diffuse color, green channel
- EST_DiffuseGreen,
- //! diffuse color, blue channel
- EST_DiffuseBlue,
- //! diffuse color, alpha channel
- EST_DiffuseAlpha,
-
- //! specular color, red channel
- EST_SpecularRed,
- //! specular color, green channel
- EST_SpecularGreen,
- //! specular color, blue channel
- EST_SpecularBlue,
- //! specular color, alpha channel
- EST_SpecularAlpha,
-
- //! specular power for phong shading
- EST_PhongPower,
-
- //! opacity between 0 and 1
- EST_Opacity,
-
- //! Marks invalid entries
- EST_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Specifies semantics for PLY elements
- *
- * Semantics define the usage of an element, e.g. vertex or material
-*/
-enum EElementSemantic
-{
- //! The element is a vertex
- EEST_Vertex = 0x0u,
-
- //! The element is a face description (index table)
- EEST_Face,
-
- //! The element is a tristrip description (index table)
- EEST_TriStrip,
-
- //! The element is an edge description (ignored)
- EEST_Edge,
-
- //! The element is a material description
- EEST_Material,
-
- //! Marks invalid entries
- EEST_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Helper class for a property in a PLY file.
- *
- * This can e.g. be a part of the vertex declaration
- */
-class Property
-{
-public:
-
- //! Default constructor
- Property()
- : eType (EDT_Int), bIsList(false), eFirstType(EDT_UChar)
- {}
-
- //! Data type of the property
- EDataType eType;
-
- //! Semantical meaning of the property
- ESemantic Semantic;
-
- //! Of the semantic of the property could not be parsed:
- //! Contains the semantic specified in the file
- std::string szName;
-
- //! Specifies whether the data type is a list where
- //! the first element specifies the size of the list
- bool bIsList;
- EDataType eFirstType;
-
- // -------------------------------------------------------------------
- //! Parse a property from a string. The end of the
- //! string is either '\n', '\r' or '\0'. Return valie is false
- //! if the input string is NOT a valid property (E.g. does
- //! not start with the "property" keyword)
- static bool ParseProperty (const char* pCur, const char** pCurOut,
- Property* pOut);
-
- // -------------------------------------------------------------------
- //! Parse a data type from a string
- static EDataType ParseDataType(const char* pCur,const char** pCurOut);
-
- // -------------------------------------------------------------------
- //! Parse a semantic from a string
- static ESemantic ParseSemantic(const char* pCur,const char** pCurOut);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Helper class for an element in a PLY file.
- *
- * This can e.g. be the vertex declaration. Elements contain a
- * well-defined number of properties.
- */
-class Element
-{
-public:
-
- //! Default constructor
- Element()
- : eSemantic (EEST_INVALID)
- , NumOccur(0)
- {}
-
- //! List of properties assigned to the element
- //! std::vector to support operator[]
- std::vector<Property> alProperties;
-
- //! Semantic of the element
- EElementSemantic eSemantic;
-
- //! Of the semantic of the element could not be parsed:
- //! Contains the semantic specified in the file
- std::string szName;
-
- //! How many times will the element occur?
- unsigned int NumOccur;
-
-
- // -------------------------------------------------------------------
- //! Parse an element from a string.
- //! The function will parse all properties contained in the
- //! element, too.
- static bool ParseElement (const char* pCur, const char** pCurOut,
- Element* pOut);
-
- // -------------------------------------------------------------------
- //! Parse a semantic from a string
- static EElementSemantic ParseSemantic(const char* pCur,
- const char** pCurOut);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Instance of a property in a PLY file
- */
-class PropertyInstance
-{
-public:
-
- //! Default constructor
- PropertyInstance ()
- {}
-
- union ValueUnion
- {
-
- //! uInt32 representation of the property. All
- // uint types are automatically converted to uint32
- uint32_t iUInt;
-
- //! Int32 representation of the property. All
- // int types are automatically converted to int32
- int32_t iInt;
-
- //! Float32 representation of the property
- float fFloat;
-
- //! Float64 representation of the property
- double fDouble;
-
- };
-
- // -------------------------------------------------------------------
- //! List of all values parsed. Contains only one value
- // for non-list properties
- std::vector<ValueUnion> avList;
-
- // -------------------------------------------------------------------
- //! Parse a property instance
- static bool ParseInstance (const char* pCur,const char** pCurOut,
- const Property* prop, PropertyInstance* p_pcOut);
-
- // -------------------------------------------------------------------
- //! Parse a property instance in binary format
- static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
- const Property* prop, PropertyInstance* p_pcOut,bool p_bBE);
-
- // -------------------------------------------------------------------
- //! Get the default value for a given data type
- static ValueUnion DefaultValue(EDataType eType);
-
- // -------------------------------------------------------------------
- //! Parse a value
- static bool ParseValue(const char* pCur,const char** pCurOut,
- EDataType eType,ValueUnion* out);
-
- // -------------------------------------------------------------------
- //! Parse a binary value
- static bool ParseValueBinary(const char* pCur,const char** pCurOut,
- EDataType eType,ValueUnion* out,bool p_bBE);
-
- // -------------------------------------------------------------------
- //! Convert a property value to a given type TYPE
- template <typename TYPE>
- static TYPE ConvertTo(ValueUnion v, EDataType eType);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Class for an element instance in a PLY file
- */
-class ElementInstance
-{
-public:
-
- //! Default constructor
- ElementInstance ()
- {}
-
- //! List of all parsed properties
- std::vector< PropertyInstance > alProperties;
-
- // -------------------------------------------------------------------
- //! Parse an element instance
- static bool ParseInstance (const char* pCur,const char** pCurOut,
- const Element* pcElement, ElementInstance* p_pcOut);
-
- // -------------------------------------------------------------------
- //! Parse a binary element instance
- static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
- const Element* pcElement, ElementInstance* p_pcOut,bool p_bBE);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Class for an element instance list in a PLY file
- */
-class ElementInstanceList
-{
-public:
-
- //! Default constructor
- ElementInstanceList ()
- {}
-
- //! List of all element instances
- std::vector< ElementInstance > alInstances;
-
- // -------------------------------------------------------------------
- //! Parse an element instance list
- static bool ParseInstanceList (const char* pCur,const char** pCurOut,
- const Element* pcElement, ElementInstanceList* p_pcOut);
-
- // -------------------------------------------------------------------
- //! Parse a binary element instance list
- static bool ParseInstanceListBinary (const char* pCur,const char** pCurOut,
- const Element* pcElement, ElementInstanceList* p_pcOut,bool p_bBE);
-};
-// ---------------------------------------------------------------------------------
-/** \brief Class to represent the document object model of an ASCII or binary
- * (both little and big-endian) PLY file
- */
-class DOM
-{
-public:
-
- //! Default constructor
- DOM()
- {}
-
-
- //! Contains all elements of the file format
- std::vector<Element> alElements;
- //! Contains the real data of each element's instance list
- std::vector<ElementInstanceList> alElementData;
-
- //! Parse the DOM for a PLY file. The input string is assumed
- //! to be terminated with zero
- static bool ParseInstance (const char* pCur,DOM* p_pcOut);
- static bool ParseInstanceBinary (const char* pCur,
- DOM* p_pcOut,bool p_bBE);
-
- //! Skip all comment lines after this
- static bool SkipComments (const char* pCur,const char** pCurOut);
-
-private:
-
- // -------------------------------------------------------------------
- //! Handle the file header and read all element descriptions
- bool ParseHeader (const char* pCur,const char** pCurOut);
-
- // -------------------------------------------------------------------
- //! Read in all element instance lists
- bool ParseElementInstanceLists (const char* pCur,const char** pCurOut);
-
- // -------------------------------------------------------------------
- //! Read in all element instance lists for a binary file format
- bool ParseElementInstanceListsBinary (const char* pCur,
- const char** pCurOut,bool p_bBE);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Helper class to represent a loaded PLY face
- */
-class Face
-{
-public:
-
- Face()
- : iMaterialIndex(0xFFFFFFFF)
- {
- // set all indices to zero by default
- mIndices.resize(3,0);
- }
-
-public:
-
- //! List of vertex indices
- std::vector<unsigned int> mIndices;
-
- //! Material index
- unsigned int iMaterialIndex;
-};
-
-// ---------------------------------------------------------------------------------
-template <typename TYPE>
-inline TYPE PLY::PropertyInstance::ConvertTo(
- PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
-{
- switch (eType)
- {
- case EDT_Float:
- return (TYPE)v.fFloat;
- case EDT_Double:
- return (TYPE)v.fDouble;
-
- case EDT_UInt:
- case EDT_UShort:
- case EDT_UChar:
- return (TYPE)v.iUInt;
-
- case EDT_Int:
- case EDT_Short:
- case EDT_Char:
- return (TYPE)v.iInt;
- default: ;
- };
- return (TYPE)0;
-}
-
-} // Namespace PLY
-} // Namespace AssImp
-
-#endif // !! include guard
diff --git a/3rdparty/assimp/code/PretransformVertices.cpp b/3rdparty/assimp/code/PretransformVertices.cpp
deleted file mode 100644
index 6da3bdf7..00000000
--- a/3rdparty/assimp/code/PretransformVertices.cpp
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file PretransformVertices.cpp
- * @brief Implementation of the "PretransformVertices" post processing step
-*/
-
-#include "AssimpPCH.h"
-#include "PretransformVertices.h"
-#include "ProcessHelper.h"
-#include "SceneCombiner.h"
-
-using namespace Assimp;
-
-// some array offsets
-#define AI_PTVS_VERTEX 0x0
-#define AI_PTVS_FACE 0x1
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-PretransformVertices::PretransformVertices()
-: configKeepHierarchy (false)
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-PretransformVertices::~PretransformVertices()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool PretransformVertices::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_PreTransformVertices) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void PretransformVertices::SetupProperties(const Importer* pImp)
-{
- // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY and AI_CONFIG_PP_PTV_NORMALIZE
- configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0));
- configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Count the number of nodes
-unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
-{
- unsigned int iRet = 1;
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
- {
- iRet += CountNodes(pcNode->mChildren[i]);
- }
- return iRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a bitwise combination identifying the vertex format of a mesh
-unsigned int PretransformVertices::GetMeshVFormat(aiMesh* pcMesh)
-{
- // the vertex format is stored in aiMesh::mBones for later retrieval.
- // there isn't a good reason to compute it a few hundred times
- // from scratch. The pointer is unused as animations are lost
- // during PretransformVertices.
- if (pcMesh->mBones)
- return (unsigned int)(uint64_t)pcMesh->mBones;
-
-
- const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
-
- // store the value for later use
- pcMesh->mBones = (aiBone**)(uint64_t)iRet;
- return iRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Count the number of vertices in the whole scene and a given
-// material index
-void PretransformVertices::CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
- unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices)
-{
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
- if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
- {
- *piVertices += pcMesh->mNumVertices;
- *piFaces += pcMesh->mNumFaces;
- }
- }
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
- {
- CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
- iVFormat,piFaces,piVertices);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collect vertex/face data
-void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
- unsigned int iVFormat, aiMesh* pcMeshOut,
- unsigned int aiCurrent[2], unsigned int* num_refs)
-{
- // No need to multiply if there's no transformation
- const bool identity = pcNode->mTransformation.IsIdentity();
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
- if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
- {
- // Decrement mesh reference counter
- unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
- ai_assert(0 != num_ref);
- --num_ref;
-
- if (identity) {
- // copy positions without modifying them
- ::memcpy(pcMeshOut->mVertices + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mVertices,
- pcMesh->mNumVertices * sizeof(aiVector3D));
-
- if (iVFormat & 0x2) {
- // copy normals without modifying them
- ::memcpy(pcMeshOut->mNormals + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mNormals,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- }
- if (iVFormat & 0x4)
- {
- // copy tangents without modifying them
- ::memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mTangents,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- // copy bitangents without modifying them
- ::memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mBitangents,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- }
- }
- else
- {
- // copy positions, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = pcNode->mTransformation * pcMesh->mVertices[n];
- }
- aiMatrix4x4 mWorldIT = pcNode->mTransformation;
- mWorldIT.Inverse().Transpose();
-
- // TODO: implement Inverse() for aiMatrix3x3
- aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
-
- if (iVFormat & 0x2)
- {
- // copy normals, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] =
- m * pcMesh->mNormals[n];
- }
- }
- if (iVFormat & 0x4)
- {
- // copy tangents and bitangents, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mTangents [aiCurrent[AI_PTVS_VERTEX]+n] = m * pcMesh->mTangents[n];
- pcMeshOut->mBitangents[aiCurrent[AI_PTVS_VERTEX]+n] = m * pcMesh->mBitangents[n];
- }
- }
- }
- unsigned int p = 0;
- while (iVFormat & (0x100 << p))
- {
- // copy texture coordinates
- memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mTextureCoords[p],
- pcMesh->mNumVertices * sizeof(aiVector3D));
- ++p;
- }
- p = 0;
- while (iVFormat & (0x1000000 << p))
- {
- // copy vertex colors
- memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mColors[p],
- pcMesh->mNumVertices * sizeof(aiColor4D));
- ++p;
- }
- // now we need to copy all faces. since we will delete the source mesh afterwards,
- // we don't need to reallocate the array of indices except if this mesh is
- // referenced multiple times.
- for (unsigned int planck = 0;planck < pcMesh->mNumFaces;++planck)
- {
- aiFace& f_src = pcMesh->mFaces[planck];
- aiFace& f_dst = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck];
-
- const unsigned int num_idx = f_src.mNumIndices;
-
- f_dst.mNumIndices = num_idx;
-
- unsigned int* pi;
- if (!num_ref) { /* if last time the mesh is referenced -> no reallocation */
- pi = f_dst.mIndices = f_src.mIndices;
-
- // offset all vertex indices
- for (unsigned int hahn = 0; hahn < num_idx;++hahn){
- pi[hahn] += aiCurrent[AI_PTVS_VERTEX];
- }
- }
- else {
- pi = f_dst.mIndices = new unsigned int[num_idx];
-
- // copy and offset all vertex indices
- for (unsigned int hahn = 0; hahn < num_idx;++hahn){
- pi[hahn] = f_src.mIndices[hahn] + aiCurrent[AI_PTVS_VERTEX];
- }
- }
-
- // Update the mPrimitiveTypes member of the mesh
- switch (pcMesh->mFaces[planck].mNumIndices)
- {
- case 0x1:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 0x2:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 0x3:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- };
- }
- aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
- aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces;
- }
- }
-
- // append all children of us
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
- CollectData(pcScene,pcNode->mChildren[i],iMat,
- iVFormat,pcMeshOut,aiCurrent,num_refs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all vertex formats that occur for a given material index
-// The output list contains duplicate elements
-void PretransformVertices::GetVFormatList( aiScene* pcScene, unsigned int iMat,
- std::list<unsigned int>& aiOut)
-{
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ i ];
- if (iMat == pcMesh->mMaterialIndex) {
- aiOut.push_back(GetMeshVFormat(pcMesh));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compute the absolute transformation matrices of each node
-void PretransformVertices::ComputeAbsoluteTransform( aiNode* pcNode )
-{
- if (pcNode->mParent) {
- pcNode->mTransformation = pcNode->mParent->mTransformation*pcNode->mTransformation;
- }
-
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
- ComputeAbsoluteTransform(pcNode->mChildren[i]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apply the node transformation to a mesh
-void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)
-{
- // Check whether we need to transform the coordinates at all
- if (!mat.IsIdentity()) {
-
- if (mesh->HasPositions()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mVertices[i] = mat * mesh->mVertices[i];
- }
- }
- if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
- aiMatrix4x4 mWorldIT = mat;
- mWorldIT.Inverse().Transpose();
-
- // TODO: implement Inverse() for aiMatrix3x3
- aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
-
- if (mesh->HasNormals()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mNormals[i] = m * mesh->mNormals[i];
- }
- }
- if (mesh->HasTangentsAndBitangents()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mTangents[i] = m * mesh->mTangents[i];
- mesh->mBitangents[i] = m * mesh->mBitangents[i];
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Simple routine to build meshes in worldspace, no further optimization
-void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
- unsigned int numIn, aiNode* node)
-{
- // NOTE:
- // aiMesh::mNumBones store original source mesh, or 0xffffffff if not a copy
- // aiMesh::mBones store reference to abs. transform we multiplied with
-
- // process meshes
- for (unsigned int i = 0; i < node->mNumMeshes;++i) {
- aiMesh* mesh = in[node->mMeshes[i]];
-
- // check whether we can operate on this mesh
- if (!mesh->mBones || *reinterpret_cast<aiMatrix4x4*>(mesh->mBones) == node->mTransformation) {
- // yes, we can.
- mesh->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
- mesh->mNumBones = 0xffffffff;
- }
- else {
-
- // try to find us in the list of newly created meshes
- for (unsigned int n = 0; n < out.size(); ++n) {
- aiMesh* ctz = out[n];
- if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4*>(ctz->mBones) == node->mTransformation) {
-
- // ok, use this one. Update node mesh index
- node->mMeshes[i] = numIn + n;
- }
- }
- if (node->mMeshes[i] < numIn) {
- // Worst case. Need to operate on a full copy of the mesh
- DefaultLogger::get()->info("PretransformVertices: Copying mesh due to mismatching transforms");
- aiMesh* ntz;
-
- const unsigned int tmp = mesh->mNumBones; //
- mesh->mNumBones = 0;
- SceneCombiner::Copy(&ntz,mesh);
- mesh->mNumBones = tmp;
-
- ntz->mNumBones = node->mMeshes[i];
- ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
-
- out.push_back(ntz);
- }
- }
- }
-
- // call children
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- BuildWCSMeshes(out,in,numIn,node->mChildren[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reset transformation matrices to identity
-void PretransformVertices::MakeIdentityTransform(aiNode* nd)
-{
- nd->mTransformation = aiMatrix4x4();
-
- // call children
- for (unsigned int i = 0; i < nd->mNumChildren;++i)
- MakeIdentityTransform(nd->mChildren[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build reference counters for all meshes
-void PretransformVertices::BuildMeshRefCountArray(aiNode* nd, unsigned int * refs)
-{
- for (unsigned int i = 0; i< nd->mNumMeshes;++i)
- refs[nd->mMeshes[i]]++;
-
- // call children
- for (unsigned int i = 0; i < nd->mNumChildren;++i)
- BuildMeshRefCountArray(nd->mChildren[i],refs);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void PretransformVertices::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("PretransformVerticesProcess begin");
-
- // Return immediately if we have no meshes
- if (!pScene->mNumMeshes)
- return;
-
- const unsigned int iOldMeshes = pScene->mNumMeshes;
- const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
- const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
-
- // first compute absolute transformation matrices for all nodes
- ComputeAbsoluteTransform(pScene->mRootNode);
-
- // Delete aiMesh::mBones for all meshes. The bones are
- // removed during this step and we need the pointer as
- // temporary storage
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- aiMesh* mesh = pScene->mMeshes[i];
-
- for (unsigned int a = 0; a < mesh->mNumBones;++a)
- delete mesh->mBones[a];
-
- delete[] mesh->mBones;
- mesh->mBones = NULL;
- }
-
- // now build a list of output meshes
- std::vector<aiMesh*> apcOutMeshes;
-
- // Keep scene hierarchy? It's an easy job in this case ...
- // we go on and transform all meshes, if one is referenced by nodes
- // with different absolute transformations a depth copy of the mesh
- // is required.
- if ( configKeepHierarchy ) {
-
- // Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
- BuildWCSMeshes(apcOutMeshes,pScene->mMeshes,pScene->mNumMeshes, pScene->mRootNode);
-
- // ... if new meshes have been generated, append them to the end of the scene
- if (apcOutMeshes.size() > 0) {
- aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()];
-
- memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes);
- memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size());
-
- pScene->mNumMeshes += apcOutMeshes.size();
- delete[] pScene->mMeshes; pScene->mMeshes = npp;
- }
-
- // now iterate through all meshes and transform them to worldspace
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- ApplyTransform(pScene->mMeshes[i],*reinterpret_cast<aiMatrix4x4*>( pScene->mMeshes[i]->mBones ));
-
- // prevent improper destruction
- pScene->mMeshes[i]->mBones = NULL;
- pScene->mMeshes[i]->mNumBones = 0;
- }
- }
- else {
-
- apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
- std::list<unsigned int> aiVFormats;
-
- std::vector<unsigned int> s(pScene->mNumMeshes,0);
- BuildMeshRefCountArray(pScene->mRootNode,&s[0]);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- // get the list of all vertex formats for this material
- aiVFormats.clear();
- GetVFormatList(pScene,i,aiVFormats);
- aiVFormats.sort();
- aiVFormats.unique();
- for (std::list<unsigned int>::const_iterator j = aiVFormats.begin();j != aiVFormats.end();++j) {
- unsigned int iVertices = 0;
- unsigned int iFaces = 0;
- CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices);
- if (0 != iFaces && 0 != iVertices)
- {
- apcOutMeshes.push_back(new aiMesh());
- aiMesh* pcMesh = apcOutMeshes.back();
- pcMesh->mNumFaces = iFaces;
- pcMesh->mNumVertices = iVertices;
- pcMesh->mFaces = new aiFace[iFaces];
- pcMesh->mVertices = new aiVector3D[iVertices];
- pcMesh->mMaterialIndex = i;
- if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices];
- if ((*j) & 0x4)
- {
- pcMesh->mTangents = new aiVector3D[iVertices];
- pcMesh->mBitangents = new aiVector3D[iVertices];
- }
- iFaces = 0;
- while ((*j) & (0x100 << iFaces))
- {
- pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
- if ((*j) & (0x10000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3;
- else pcMesh->mNumUVComponents[iFaces] = 2;
- iFaces++;
- }
- iFaces = 0;
- while ((*j) & (0x1000000 << iFaces))
- pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
-
- // fill the mesh ...
- unsigned int aiTemp[2] = {0,0};
- CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp,&s[0]);
- }
- }
- }
-
- // now delete all meshes in the scene and build a new mesh list
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiMesh* mesh = pScene->mMeshes[i];
- mesh->mNumBones = 0;
- mesh->mBones = NULL;
-
- // we're reusing the face index arrays. avoid destruction
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
- mesh->mFaces[a].mNumIndices = 0;
- mesh->mFaces[a].mIndices = NULL;
- }
-
- delete mesh;
-
- // Invalidate the contents of the old mesh array. We will most
- // likely have less output meshes now, so the last entries of
- // the mesh array are not overridden. We set them to NULL to
- // make sure the developer gets notified when his application
- // attempts to access these fields ...
- mesh = NULL;
- }
-
- // If no meshes are referenced in the node graph it is possible that we get no output meshes.
- if (apcOutMeshes.empty()) {
- throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by nodes");
- }
- else
- {
- // It is impossible that we have more output meshes than
- // input meshes, so we can easily reuse the old mesh array
- pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i] = apcOutMeshes[i];
- }
- }
-
- // remove all animations from the scene
- for (unsigned int i = 0; i < pScene->mNumAnimations;++i)
- delete pScene->mAnimations[i];
- delete[] pScene->mAnimations;
-
- pScene->mAnimations = NULL;
- pScene->mNumAnimations = 0;
-
- // --- we need to keep all cameras and lights
- for (unsigned int i = 0; i < pScene->mNumCameras;++i)
- {
- aiCamera* cam = pScene->mCameras[i];
- const aiNode* nd = pScene->mRootNode->FindNode(cam->mName);
- ai_assert(NULL != nd);
-
- // multiply all properties of the camera with the absolute
- // transformation of the corresponding node
- cam->mPosition = nd->mTransformation * cam->mPosition;
- cam->mLookAt = aiMatrix3x3( nd->mTransformation ) * cam->mLookAt;
- cam->mUp = aiMatrix3x3( nd->mTransformation ) * cam->mUp;
- }
-
- for (unsigned int i = 0; i < pScene->mNumLights;++i)
- {
- aiLight* l = pScene->mLights[i];
- const aiNode* nd = pScene->mRootNode->FindNode(l->mName);
- ai_assert(NULL != nd);
-
- // multiply all properties of the camera with the absolute
- // transformation of the corresponding node
- l->mPosition = nd->mTransformation * l->mPosition;
- l->mDirection = aiMatrix3x3( nd->mTransformation ) * l->mDirection;
- }
-
- if ( !configKeepHierarchy ) {
-
- // now delete all nodes in the scene and build a new
- // flat node graph with a root node and some level 1 children
- delete pScene->mRootNode;
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<dummy_root>");
-
- if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
- {
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode->mNumChildren = pScene->mNumMeshes+pScene->mNumLights+pScene->mNumCameras;
- aiNode** nodes = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
-
- // generate mesh nodes
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.length = ::sprintf(pcNode->mName.data,"mesh_%i",i);
-
- // setup mesh indices
- pcNode->mNumMeshes = 1;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- }
- // generate light nodes
- for (unsigned int i = 0; i < pScene->mNumLights;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.length = ::sprintf(pcNode->mName.data,"light_%i",i);
- pScene->mLights[i]->mName = pcNode->mName;
- }
- // generate camera nodes
- for (unsigned int i = 0; i < pScene->mNumCameras;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.length = ::sprintf(pcNode->mName.data,"cam_%i",i);
- pScene->mCameras[i]->mName = pcNode->mName;
- }
- }
- }
- else {
- // ... and finally set the transformation matrix of all nodes to identity
- MakeIdentityTransform(pScene->mRootNode);
- }
-
- if (configNormalize) {
- // compute the boundary of all meshes
- aiVector3D min,max;
- MinMaxChooser<aiVector3D> ()(min,max);
-
- for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
- aiMesh* m = pScene->mMeshes[a];
- for (unsigned int i = 0; i < m->mNumVertices;++i) {
- min = std::min(m->mVertices[i],min);
- max = std::max(m->mVertices[i],max);
- }
- }
-
- // find the dominant axis
- aiVector3D d = max-min;
- const float div = std::max(d.x,std::max(d.y,d.z))*0.5f;
-
- d = min+d*0.5f;
- for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
- aiMesh* m = pScene->mMeshes[a];
- for (unsigned int i = 0; i < m->mNumVertices;++i) {
- m->mVertices[i] = (m->mVertices[i]-d)/div;
- }
- }
- }
-
- // print statistics
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[4096];
-
- DefaultLogger::get()->debug("PretransformVerticesProcess finished");
-
- sprintf(buffer,"Removed %i nodes and %i animation channels (%i output nodes)",
- iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode));
- DefaultLogger::get()->info(buffer);
-
- sprintf(buffer,"Kept %i lights and %i cameras",
- pScene->mNumLights,pScene->mNumCameras);
- DefaultLogger::get()->info(buffer);
-
- sprintf(buffer,"Moved %i meshes to WCS (number of output meshes: %i)",
- iOldMeshes,pScene->mNumMeshes);
- DefaultLogger::get()->info(buffer);
- }
-}
-
diff --git a/3rdparty/assimp/code/PretransformVertices.h b/3rdparty/assimp/code/PretransformVertices.h
deleted file mode 100644
index 41f2f38e..00000000
--- a/3rdparty/assimp/code/PretransformVertices.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file PretransformVertices.h
- * @brief Defines a post processing step to pretransform all
- * vertices in the scenegraph
- */
-#ifndef AI_PRETRANSFORMVERTICES_H_INC
-#define AI_PRETRANSFORMVERTICES_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class PretransformVerticesTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** The PretransformVertices pretransforms all vertices in the nodegraph
- * and removes the whole graph. The output is a list of meshes, one for
- * each material.
-*/
-class ASSIMP_API PretransformVertices : public BaseProcess
-{
- friend class Importer;
- friend class ::PretransformVerticesTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- PretransformVertices ();
-
- /** Destructor, private as well */
- ~PretransformVertices ();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Toggle the 'keep hierarchy' option
- * @param d hm ... difficult to guess what this means, hu!?
- */
- void KeepHierarchy(bool d) {
- configKeepHierarchy = d;
- }
-
- // -------------------------------------------------------------------
- /** @brief Check whether 'keep hierarchy' is currently enabled.
- * @return ...
- */
- bool IsHierarchyKept() const {
- return configKeepHierarchy;
- }
-
-private:
-
- // -------------------------------------------------------------------
- // Count the number of nodes
- unsigned int CountNodes( aiNode* pcNode );
-
- // -------------------------------------------------------------------
- // Get a bitwise combination identifying the vertex format of a mesh
- unsigned int GetMeshVFormat(aiMesh* pcMesh);
-
- // -------------------------------------------------------------------
- // Count the number of vertices in the whole scene and a given
- // material index
- void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode,
- unsigned int iMat,
- unsigned int iVFormat,
- unsigned int* piFaces,
- unsigned int* piVertices);
-
- // -------------------------------------------------------------------
- // Collect vertex/face data
- void CollectData( aiScene* pcScene, aiNode* pcNode,
- unsigned int iMat,
- unsigned int iVFormat,
- aiMesh* pcMeshOut,
- unsigned int aiCurrent[2],
- unsigned int* num_refs);
-
- // -------------------------------------------------------------------
- // Get a list of all vertex formats that occur for a given material
- // The output list contains duplicate elements
- void GetVFormatList( aiScene* pcScene, unsigned int iMat,
- std::list<unsigned int>& aiOut);
-
- // -------------------------------------------------------------------
- // Compute the absolute transformation matrices of each node
- void ComputeAbsoluteTransform( aiNode* pcNode );
-
- // -------------------------------------------------------------------
- // Simple routine to build meshes in worldspace, no further optimization
- void BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
- unsigned int numIn, aiNode* node);
-
- // -------------------------------------------------------------------
- // Apply the node transformation to a mesh
- void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat);
-
- // -------------------------------------------------------------------
- // Reset transformation matrices to identity
- void MakeIdentityTransform(aiNode* nd);
-
- // -------------------------------------------------------------------
- // Build reference counters for all meshes
- void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs);
-
-
-
- //! Configuration option: keep scene hierarchy as long as possible
- bool configKeepHierarchy, configNormalize;
-
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENFACENORMALPROCESS_H_INC
diff --git a/3rdparty/assimp/code/ProcessHelper.h b/3rdparty/assimp/code/ProcessHelper.h
deleted file mode 100644
index 349da173..00000000
--- a/3rdparty/assimp/code/ProcessHelper.h
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef AI_PROCESS_HELPER_H_INCLUDED
-#define AI_PROCESS_HELPER_H_INCLUDED
-
-#include "../include/aiPostProcess.h"
-
-#include "SpatialSort.h"
-#include "BaseProcess.h"
-#include "ParsingUtils.h"
-
-// -------------------------------------------------------------------------------
-// Some extensions to std namespace. Mainly std::min and std::max for all
-// flat data types in the aiScene. They're used to quickly determine the
-// min/max bounds of data arrays.
-#ifdef __cplusplus
-namespace std {
-
- // std::min for aiVector3D
- inline ::aiVector3D min (const ::aiVector3D& a, const ::aiVector3D& b) {
- return ::aiVector3D (min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
- }
-
- // std::max for aiVector3D
- inline ::aiVector3D max (const ::aiVector3D& a, const ::aiVector3D& b) {
- return ::aiVector3D (max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
- }
-
- // std::min for aiColor4D
- inline ::aiColor4D min (const ::aiColor4D& a, const ::aiColor4D& b) {
- return ::aiColor4D (min(a.r,b.r),min(a.g,b.g),min(a.b,b.b),min(a.a,b.a));
- }
-
- // std::max for aiColor4D
- inline ::aiColor4D max (const ::aiColor4D& a, const ::aiColor4D& b) {
- return ::aiColor4D (max(a.r,b.r),max(a.g,b.g),max(a.b,b.b),max(a.a,b.a));
- }
-
- // std::min for aiQuaternion
- inline ::aiQuaternion min (const ::aiQuaternion& a, const ::aiQuaternion& b) {
- return ::aiQuaternion (min(a.w,b.w),min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
- }
-
- // std::max for aiQuaternion
- inline ::aiQuaternion max (const ::aiQuaternion& a, const ::aiQuaternion& b) {
- return ::aiQuaternion (max(a.w,b.w),max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
- }
-
- // std::min for aiVectorKey
- inline ::aiVectorKey min (const ::aiVectorKey& a, const ::aiVectorKey& b) {
- return ::aiVectorKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
- }
-
- // std::max for aiVectorKey
- inline ::aiVectorKey max (const ::aiVectorKey& a, const ::aiVectorKey& b) {
- return ::aiVectorKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
- }
-
- // std::min for aiQuatKey
- inline ::aiQuatKey min (const ::aiQuatKey& a, const ::aiQuatKey& b) {
- return ::aiQuatKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
- }
-
- // std::max for aiQuatKey
- inline ::aiQuatKey max (const ::aiQuatKey& a, const ::aiQuatKey& b) {
- return ::aiQuatKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
- }
-
- // std::min for aiVertexWeight
- inline ::aiVertexWeight min (const ::aiVertexWeight& a, const ::aiVertexWeight& b) {
- return ::aiVertexWeight (min(a.mVertexId,b.mVertexId),min(a.mWeight,b.mWeight));
- }
-
- // std::max for aiVertexWeight
- inline ::aiVertexWeight max (const ::aiVertexWeight& a, const ::aiVertexWeight& b) {
- return ::aiVertexWeight (max(a.mVertexId,b.mVertexId),max(a.mWeight,b.mWeight));
- }
-
-} // end namespace std
-#endif // !! C++
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-// Start points for ArrayBounds<T> for all supported Ts
-template <typename T>
-struct MinMaxChooser;
-
-template <> struct MinMaxChooser<float> {
- void operator ()(float& min,float& max) {
- max = -10e10f;
- min = 10e10f;
-}};
-template <> struct MinMaxChooser<double> {
- void operator ()(double& min,double& max) {
- max = -10e10;
- min = 10e10;
-}};
-template <> struct MinMaxChooser<unsigned int> {
- void operator ()(unsigned int& min,unsigned int& max) {
- max = 0;
- min = (1u<<(sizeof(unsigned int)*8-1));
-}};
-
-template <> struct MinMaxChooser<aiVector3D> {
- void operator ()(aiVector3D& min,aiVector3D& max) {
- max = aiVector3D(-10e10f,-10e10f,-10e10f);
- min = aiVector3D( 10e10f, 10e10f, 10e10f);
-}};
-template <> struct MinMaxChooser<aiColor4D> {
- void operator ()(aiColor4D& min,aiColor4D& max) {
- max = aiColor4D(-10e10f,-10e10f,-10e10f,-10e10f);
- min = aiColor4D( 10e10f, 10e10f, 10e10f, 10e10f);
-}};
-
-template <> struct MinMaxChooser<aiQuaternion> {
- void operator ()(aiQuaternion& min,aiQuaternion& max) {
- max = aiQuaternion(-10e10f,-10e10f,-10e10f,-10e10f);
- min = aiQuaternion( 10e10f, 10e10f, 10e10f, 10e10f);
-}};
-
-template <> struct MinMaxChooser<aiVectorKey> {
- void operator ()(aiVectorKey& min,aiVectorKey& max) {
- MinMaxChooser<double>()(min.mTime,max.mTime);
- MinMaxChooser<aiVector3D>()(min.mValue,max.mValue);
-}};
-template <> struct MinMaxChooser<aiQuatKey> {
- void operator ()(aiQuatKey& min,aiQuatKey& max) {
- MinMaxChooser<double>()(min.mTime,max.mTime);
- MinMaxChooser<aiQuaternion>()(min.mValue,max.mValue);
-}};
-
-template <> struct MinMaxChooser<aiVertexWeight> {
- void operator ()(aiVertexWeight& min,aiVertexWeight& max) {
- MinMaxChooser<unsigned int>()(min.mVertexId,max.mVertexId);
- MinMaxChooser<float>()(min.mWeight,max.mWeight);
-}};
-
-// -------------------------------------------------------------------------------
-/** @brief Find the min/max values of an array of Ts
- * @param in Input array
- * @param size Numebr of elements to process
- * @param[out] min minimum value
- * @param[out] max maximum value
- */
-template <typename T>
-inline void ArrayBounds(const T* in, unsigned int size, T& min, T& max)
-{
- MinMaxChooser<T> ()(min,max);
- for (unsigned int i = 0; i < size;++i) {
- min = std::min(in[i],min);
- max = std::max(in[i],max);
- }
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Extract single strings from a list of identifiers
- * @param in Input string list.
- * @param out Receives a list of clean output strings
- * @sdee #AI_CONFIG_PP_OG_EXCLUDE_LIST
- */
-inline void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
-{
- const char* s = in.c_str();
- while (*s) {
- SkipSpacesAndLineEnd(&s);
- if (*s == '\'') {
- const char* base = ++s;
- while (*s != '\'') {
- ++s;
- if (*s == '\0') {
- DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted");
- return;
- }
- }
- out.push_back(std::string(base,(size_t)(s-base)));
- ++s;
- }
- else {
- out.push_back(GetNextToken(s));
- }
- }
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Compute the newell normal of a polygon regardless of its shape
- *
- * @param out Receives the output normal
- * @param num Number of input vertices
- * @param x X data source. x[ofs_x*n] is the n'th element.
- * @param y Y data source. y[ofs_y*n] is the y'th element
- * @param z Z data source. z[ofs_z*n] is the z'th element
- *
- * @note The data arrays must have storage for at least num+2 elements. Using
- * this method is much faster than the 'other' NewellNormal()
- */
-template <int ofs_x, int ofs_y, int ofs_z>
-inline void NewellNormal (aiVector3D& out, int num, float* x, float* y, float* z)
-{
- // Duplicate the first two vertices at the end
- x[(num+0)*ofs_x] = x[0];
- x[(num+1)*ofs_x] = x[ofs_x];
-
- y[(num+0)*ofs_y] = y[0];
- y[(num+1)*ofs_y] = y[ofs_y];
-
- z[(num+0)*ofs_z] = z[0];
- z[(num+1)*ofs_z] = z[ofs_z];
-
- float sum_xy = 0.0, sum_yz = 0.0, sum_zx = 0.0;
-
- float *xptr = x +ofs_x, *xlow = x, *xhigh = x + ofs_x*2;
- float *yptr = y +ofs_y, *ylow = y, *yhigh = y + ofs_y*2;
- float *zptr = z +ofs_z, *zlow = z, *zhigh = z + ofs_z*2;
-
- for (int tmp=0; tmp < num; tmp++) {
- sum_xy += (*xptr) * ( (*yhigh) - (*ylow) );
- sum_yz += (*yptr) * ( (*zhigh) - (*zlow) );
- sum_zx += (*zptr) * ( (*xhigh) - (*xlow) );
-
- xptr += ofs_x;
- xlow += ofs_x;
- xhigh += ofs_x;
-
- yptr += ofs_y;
- ylow += ofs_y;
- yhigh += ofs_y;
-
- zptr += ofs_z;
- zlow += ofs_z;
- zhigh += ofs_z;
- }
- out = aiVector3D(sum_yz,sum_zx,sum_xy);
-}
-
-#if 0
-// -------------------------------------------------------------------------------
-/** @brief Compute newell normal of a polgon regardless of its shape
- *
- * @param out Receives the output normal
- * @param data Input vertices
- * @param idx Index buffer
- * @param num Number of indices
- */
-inline void NewellNormal (aiVector3D& out, const aiVector3D* data, unsigned int* idx, unsigned int num )
-{
- // TODO: intended to be used in GenNormals.
-}
-#endif
-
-// -------------------------------------------------------------------------------
-/** Little helper function to calculate the quadratic difference
- * of two colours.
- * @param pColor1 First color
- * @param pColor2 second color
- * @return Quadratic color difference
- */
-inline float GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pColor2)
-{
- const aiColor4D c (pColor1.r - pColor2.r, pColor1.g - pColor2.g,
- pColor1.b - pColor2.b, pColor1.a - pColor2.a);
-
- return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a;
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Compute the AABB of a mesh after applying a given transform
- * @param mesh Input mesh
- * @param[out] min Receives minimum transformed vertex
- * @param[out] max Receives maximum transformed vertex
- * @param m Transformation matrix to be applied
- */
-inline void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
- const aiMatrix4x4& m)
-{
- min = aiVector3D (10e10f, 10e10f, 10e10f);
- max = aiVector3D (-10e10f,-10e10f,-10e10f);
- for (unsigned int i = 0;i < mesh->mNumVertices;++i)
- {
- const aiVector3D v = m * mesh->mVertices[i];
- min = std::min(v,min);
- max = std::max(v,max);
- }
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to determine the 'real' center of a mesh
- *
- * That is the center of its axis-aligned bounding box.
- * @param mesh Input mesh
- * @param[out] min Minimum vertex of the mesh
- * @param[out] max maximum vertex of the mesh
- * @param[out] out Center point
- */
-inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max)
-{
- ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max);
- out = min + (max-min)*0.5f;
-}
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh after applying a given transform
-inline void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,
- aiVector3D& max, const aiMatrix4x4& m)
-{
- FindAABBTransformed(mesh,min,max,m);
- out = min + (max-min)*0.5f;
-}
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh
-inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out)
-{
- aiVector3D min,max;
- FindMeshCenter(mesh,out,min,max);
-}
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh after applying a given transform
-inline void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
- const aiMatrix4x4& m)
-{
- aiVector3D min,max;
- FindMeshCenterTransformed(mesh,out,min,max,m);
-}
-
-// -------------------------------------------------------------------------------
-// Compute a good epsilon value for position comparisons on a mesh
-inline float ComputePositionEpsilon(const aiMesh* pMesh)
-{
- const float epsilon = 1e-4f;
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec, maxVec;
- ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec);
- return (maxVec - minVec).Length() * epsilon;
-}
-
-// -------------------------------------------------------------------------------
-// Compute a good epsilon value for position comparisons on a array of meshes
-inline float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
-{
- const float epsilon = 1e-4f;
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec, maxVec, mi, ma;
- MinMaxChooser<aiVector3D>()(minVec,maxVec);
-
- for (size_t a = 0; a < num; ++a) {
- const aiMesh* pMesh = pMeshes[a];
- ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma);
-
- minVec = std::min(minVec,mi);
- maxVec = std::max(maxVec,ma);
- }
- return (maxVec - minVec).Length() * epsilon;
-}
-
-// -------------------------------------------------------------------------------
-// Compute an unique value for the vertex format of a mesh
-inline unsigned int GetMeshVFormatUnique(aiMesh* pcMesh)
-{
- ai_assert(NULL != pcMesh);
-
- // FIX: the hash may never be 0. Otherwise a comparison against
- // nullptr could be successful
- unsigned int iRet = 1;
-
- // normals
- if (pcMesh->HasNormals())iRet |= 0x2;
- // tangents and bitangents
- if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4;
-
-#ifdef BOOST_STATIC_ASSERT
- BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
- BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
-#endif
-
- // texture coordinates
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- iRet |= (0x100 << p);
- if (3 == pcMesh->mNumUVComponents[p])
- iRet |= (0x10000 << p);
-
- ++p;
- }
- // vertex colors
- p = 0;
- while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++);
- return iRet;
-}
-
-typedef std::pair <unsigned int,float> PerVertexWeight;
-typedef std::vector <PerVertexWeight> VertexWeightTable;
-
-// -------------------------------------------------------------------------------
-// Compute a per-vertex bone weight table
-// please .... delete result with operator delete[] ...
-inline VertexWeightTable* ComputeVertexBoneWeightTable(aiMesh* pMesh)
-{
- if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones)
- return NULL;
-
- VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
- for (unsigned int i = 0; i < pMesh->mNumBones;++i)
- {
- aiBone* bone = pMesh->mBones[i];
- for (unsigned int a = 0; a < bone->mNumWeights;++a) {
- const aiVertexWeight& weight = bone->mWeights[a];
- avPerVertexWeights[weight.mVertexId].push_back(
- std::pair<unsigned int,float>(i,weight.mWeight));
- }
- }
- return avPerVertexWeights;
-}
-
-// -------------------------------------------------------------------------------
-// Get a string for a given aiTextureType
-inline const char* TextureTypeToString(aiTextureType in)
-{
- switch (in)
- {
- case aiTextureType_NONE:
- return "n/a";
- case aiTextureType_DIFFUSE:
- return "Diffuse";
- case aiTextureType_SPECULAR:
- return "Specular";
- case aiTextureType_AMBIENT:
- return "Ambient";
- case aiTextureType_EMISSIVE:
- return "Emissive";
- case aiTextureType_OPACITY:
- return "Opacity";
- case aiTextureType_NORMALS:
- return "Normals";
- case aiTextureType_HEIGHT:
- return "Height";
- case aiTextureType_SHININESS:
- return "Shininess";
- case aiTextureType_DISPLACEMENT:
- return "Displacement";
- case aiTextureType_LIGHTMAP:
- return "Lightmap";
- case aiTextureType_REFLECTION:
- return "Reflection";
- case aiTextureType_UNKNOWN:
- return "Unknown";
- default:
- return "HUGE ERROR. Expect BSOD (linux guys: kernel panic ...).";
- }
-}
-
-// -------------------------------------------------------------------------------
-// Get a string for a given aiTextureMapping
-inline const char* MappingTypeToString(aiTextureMapping in)
-{
- switch (in)
- {
- case aiTextureMapping_UV:
- return "UV";
- case aiTextureMapping_BOX:
- return "Box";
- case aiTextureMapping_SPHERE:
- return "Sphere";
- case aiTextureMapping_CYLINDER:
- return "Cylinder";
- case aiTextureMapping_PLANE:
- return "Plane";
- case aiTextureMapping_OTHER:
- return "Other";
- default:
- return "HUGE ERROR. Expect BSOD (linux guys: kernel panic ...).";
- }
-}
-
-// -------------------------------------------------------------------------------
-// Utility postprocess step to share the spatial sort tree between
-// all steps which use it to speedup its computations.
-class ComputeSpatialSortProcess : public BaseProcess
-{
- bool IsActive( unsigned int pFlags) const
- {
- return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
- aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
- }
-
- void Execute( aiScene* pScene)
- {
- typedef std::pair<SpatialSort, float> _Type;
- DefaultLogger::get()->debug("Generate spatially-sorted vertex cache");
-
- std::vector<_Type>* p = new std::vector<_Type>(pScene->mNumMeshes);
- std::vector<_Type>::iterator it = p->begin();
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it) {
- aiMesh* mesh = pScene->mMeshes[i];
- _Type& blubb = *it;
- blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D));
- blubb.second = ComputePositionEpsilon(mesh);
- }
-
- shared->AddProperty(AI_SPP_SPATIAL_SORT,p);
- }
-};
-
-// -------------------------------------------------------------------------------
-// ... and the same again to cleanup the whole stuff
-class DestroySpatialSortProcess : public BaseProcess
-{
- bool IsActive( unsigned int pFlags) const
- {
- return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
- aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
- }
-
- void Execute( aiScene* /*pScene*/)
- {
- shared->RemoveProperty(AI_SPP_SPATIAL_SORT);
- }
-};
-
-} // ! namespace Assimp
-#endif // !! AI_PROCESS_HELPER_H_INCLUDED
diff --git a/3rdparty/assimp/code/Profiler.h b/3rdparty/assimp/code/Profiler.h
deleted file mode 100644
index 74fed429..00000000
--- a/3rdparty/assimp/code/Profiler.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Profiler.h
- * @brief Utility to measure the respective runtime of each import step
- */
-#ifndef INCLUDED_PROFILER_H
-#define INCLUDED_PROFILER_H
-
-#include "boost/timer.hpp"
-
-#include "../include/DefaultLogger.h"
-#include "TinyFormatter.h"
-
-namespace Assimp {
- namespace Profiling {
-
- using namespace Formatter;
-
-
-// ------------------------------------------------------------------------------------------------
-/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
- * dumped to the log file.
- */
-class Profiler
-{
-
-public:
-
- Profiler() {}
-
-public:
-
- /** Start a named timer */
- void BeginRegion(const std::string& region) {
- regions[region] = boost::timer();
- DefaultLogger::get()->debug((format("START `"),region,"`"));
- }
-
-
- /** End a specific named timer and write its end time to the log */
- void EndRegion(const std::string& region) {
- RegionMap::const_iterator it = regions.find(region);
- if (it == regions.end()) {
- return;
- }
-
- DefaultLogger::get()->debug((format("END `"),region,"`, dt= ",(*it).second.elapsed()," s"));
- }
-
-private:
-
- typedef std::map<std::string,boost::timer> RegionMap;
- RegionMap regions;
-};
-
- }
-}
-
-#endif
diff --git a/3rdparty/assimp/code/Q3BSPFileData.h b/3rdparty/assimp/code/Q3BSPFileData.h
deleted file mode 100644
index 22e37a34..00000000
--- a/3rdparty/assimp/code/Q3BSPFileData.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#ifndef ASSIMP_Q3BSPFILEDATA_H_INC
-#define ASSIMP_Q3BSPFILEDATA_H_INC
-
-#include <vector>
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-static const unsigned int CE_BSP_LIGHTMAPWIDTH = 128;
-static const unsigned int CE_BSP_LIGHTMAPHEIGHT = 128;
-
-static const unsigned int CE_BSP_LIGHTMAPSIZE = 128*128*3; ///< = 128( width ) * 128 ( height ) * 3 ( channels / RGB ).
-static const int VERION_Q3LEVEL = 46; ///< Supported version.
-
-/// Geometric type enumeration
-enum Q3BSPGeoType
-{
- Polygon = 1,
- Patch,
- TriangleMesh,
- Billboard
-};
-
-/// Integer vector.
-struct ceVec3i
-{
- int x, y, z;
- ceVec3i(): x( 0 ), y( 0 ), z( 0 ) { /* empty */ }
- ceVec3i( int iX, int iY=0, int iZ=0) : x( iX ), y( iY ), z( iZ ) { /* empty */ }
-};
-
-/// Fileheader
-struct sQ3BSPHeader
-{
- char strID[ 4 ]; //!< Should be "IBSP"
- int iVersion; //!< 46 for standard levels
-};
-
-/// Descripes an entry.
-struct sQ3BSPLump
-{
- int iOffset; ///< Offset from startpointer of file
- int iSize; ///< Size fo part
-};
-
-struct vec2f
-{
- float x,y;
-};
-
-struct vec3f
-{
- float x, y, z;
-};
-
-/// Vertex of a Q3 level
-struct sQ3BSPVertex
-{
- vec3f vPosition; ///< Position of vertex
- vec2f vTexCoord; ///< (u,v) Texturecoordinate of detailtexture
- vec2f vLightmap; ///< (u,v) Texturecoordinate of lightmap
- vec3f vNormal; ///< vertex normale
- unsigned char bColor[ 4 ]; ///< Color in RGBA
-};
-
-/// A face in bsp format info
-struct sQ3BSPFace
-{
- int iTextureID; ///< Index in texture array
- int iEffect; ///< Index in effectarray (-1 = no effect)
- int iType; ///< 1=Polygon, 2=Patch, 3=Mesh, 4=Billboard
- int iVertexIndex; ///< Start index of polygon
- int iNumOfVerts; ///< Number of vertices
- int iFaceVertexIndex; ///< Index of first mesh vertex
- int iNumOfFaceVerts; ///< Anzahl der Meshvertices
- int iLightmapID; ///< Index to the lightmap array
- int iLMapCorner[ 2 ]; ///< Die Ecke der Lightmap in der Textur
- int iLMapSize[ 2 ]; ///< Size of the lightmap stored on the texture
- vec3f vLMapPos; ///< 3D-Ursprung der Lightmap
- vec3f vLMapVecs[ 2 ]; ///< 3D-s-t-Vektoren
- vec3f vNormal; ///< Polygonnormale
- int patchWidth, patchHeight; ///< bezier patch
-};
-
-/// A quake3 texture name.
-struct sQ3BSPTexture
-{
- char strName[ 64 ]; ///< Name of the texture without extention
- int iFlags; ///< Not used
- int iContents; ///< Not used
-};
-
-/// A lightmap of the level, size 128 x 128, RGB components.
-struct sQ3BSPLightmap
-{
- unsigned char bLMapData[ CE_BSP_LIGHTMAPSIZE ];
- sQ3BSPLightmap()
- {
- memset(bLMapData, 0, CE_BSP_LIGHTMAPSIZE );
- }
-};
-
-struct SubPatch
-{
- std::vector<size_t> indices;
- int lightmapID;
-};
-
-enum eLumps
-{
- kEntities = 0,
- kTextures,
- kPlanes,
- kNodes,
- kLeafs,
- kLeafFaces,
- kLeafBrushes,
- kModels,
- kBrushes,
- kBrushSides,
- kVertices,
- kMeshVerts,
- kShaders,
- kFaces,
- kLightmaps,
- kLightVolumes,
- kVisData,
- kMaxLumps
-};
-
-struct Q3BSPModel
-{
- std::vector<unsigned char> m_Data;
- std::vector<sQ3BSPLump*> m_Lumps;
- std::vector<sQ3BSPVertex*> m_Vertices;
- std::vector<sQ3BSPFace*> m_Faces;
- std::vector<int> m_Indices;
- std::vector<sQ3BSPTexture*> m_Textures;
- std::vector<sQ3BSPLightmap*> m_Lightmaps;
- std::vector<char> m_EntityData;
- std::string m_ModelName;
-
- Q3BSPModel() :
- m_Data(),
- m_Lumps(),
- m_Vertices(),
- m_Faces(),
- m_Indices(),
- m_Textures(),
- m_Lightmaps(),
- m_EntityData(),
- m_ModelName( "" )
- {
- // empty
- }
-
- ~Q3BSPModel()
- {
- for ( unsigned int i=0; i<m_Lumps.size(); i++ )
- if ( NULL != m_Lumps[i] )
- delete m_Lumps[i];
-
- for ( unsigned int i=0; i<m_Vertices.size(); i++ )
- if ( NULL != m_Vertices[ i ] )
- delete m_Vertices[ i ];
- for ( unsigned int i=0; i<m_Faces.size(); i++ )
- if ( NULL != m_Faces[ i ] )
- delete m_Faces[ i ];
- for ( unsigned int i=0; i<m_Textures.size(); i++ )
- if ( NULL != m_Textures[ i ] )
- delete m_Textures[ i ];
- for ( unsigned int i=0; i<m_Lightmaps.size(); i++ )
- if ( NULL != m_Lightmaps[ i ] )
- delete m_Lightmaps[ i ];
-
- m_Lumps.clear();
- m_Vertices.clear();
- m_Faces.clear();
- m_Textures.clear();
- m_Lightmaps.clear();
- }
-};
-
-} // Namespace Q3BSP
-} // Namespace Assimp
-
-#endif // ASSIMP_Q3BSPFILEDATA_H_INC
diff --git a/3rdparty/assimp/code/Q3BSPFileImporter.cpp b/3rdparty/assimp/code/Q3BSPFileImporter.cpp
deleted file mode 100644
index ce198c49..00000000
--- a/3rdparty/assimp/code/Q3BSPFileImporter.cpp
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----------------------------------------------------------------------------------------------------
-*/
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-
-//#include <windows.h>
-#include "DefaultIOSystem.h"
-#include "Q3BSPFileImporter.h"
-#include "Q3BSPZipArchive.h"
-#include "Q3BSPFileParser.h"
-#include "Q3BSPFileData.h"
-
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-#else
-# include "../contrib/zlib/zlib.h"
-#endif
-
-#include "../include/aiTypes.h"
-#include "../include/aiMesh.h"
-#include <vector>
-
-namespace Assimp
-{
-
-using namespace Q3BSP;
-
-static const std::string Q3BSPExtention = "pk3";
-
-// ------------------------------------------------------------------------------------------------
-// Local fnction to create a material keyname.
-static void createKey( int id1, int id2, std::string &rKey )
-{
- std::stringstream str;
- str << id1 << "." << id2;
- rKey = str.str();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Local function to extract the texture ids from a material keyname.
-static void extractIds( const std::string &rKey, int &rId1, int &rId2 )
-{
- rId1 = -1;
- rId2 = -1;
- if ( rKey.empty() )
- return;
-
- std::string::size_type pos = rKey.find( "." );
- if ( std::string::npos == pos )
- return;
-
- std::string tmp1 = rKey.substr( 0, pos );
- std::string tmp2 = rKey.substr( pos + 1, rKey.size() - pos - 1 );
- rId1 = atoi( tmp1.c_str() );
- rId2 = atoi( tmp2.c_str() );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Local helper fuction to normalize filenames.
-static void normalizePathName( const std::string &rPath, std::string &rNormalizedPath )
-{
- rNormalizedPath = "";
- if ( rPath.empty() )
- return;
-
-#ifdef _WIN32
- std::string sep = "\\";
-#else
- std::string sep = "/";
-#endif
-
- static const unsigned int numDelimiters = 2;
- const char delimiters[ numDelimiters ] = { '/', '\\' };
- rNormalizedPath = rPath;
- for ( unsigned int i=0; i<numDelimiters; i++ )
- {
- for ( size_t j=0; j<rNormalizedPath.size(); j++ )
- {
- if ( rNormalizedPath[j] == delimiters[ i ] )
- {
- rNormalizedPath[ j ] = sep[ 0 ];
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-Q3BSPFileImporter::Q3BSPFileImporter() :
- m_pCurrentMesh( NULL ),
- m_pCurrentFace( NULL ),
- m_MaterialLookupMap(),
- mTextures()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-Q3BSPFileImporter::~Q3BSPFileImporter()
-{
- // For lint
- m_pCurrentMesh = NULL;
- m_pCurrentFace = NULL;
-
- // Clear face-to-material map
- for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
- ++it )
- {
- const std::string matName = (*it).first;
- if ( matName.empty() )
- {
- continue;
- }
-
- std::vector<Q3BSP::sQ3BSPFace*> *pCurFaceArray = (*it).second;
- if ( NULL != pCurFaceArray )
- {
- delete pCurFaceArray;
- }
- }
- m_MaterialLookupMap.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the loader can read this.
-bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
-{
- bool isBSPData = false;
- if ( checkSig )
- isBSPData = SimpleExtensionCheck( rFile, Q3BSPExtention.c_str() );
-
- return isBSPData;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Adds extensions.
-void Q3BSPFileImporter::GetExtensionList( std::set<std::string>& extensions )
-{
- extensions.insert( Q3BSPExtention );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Import method.
-void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/)
-{
- Q3BSPZipArchive Archive( rFile );
- if ( !Archive.isOpen() )
- {
- throw new DeadlyImportError( "Failed to open file " + rFile + "." );
- }
-
- std::string archiveName( "" ), mapName( "" );
- separateMapName( rFile, archiveName, mapName );
-
- if ( mapName.empty() )
- {
- if ( !findFirstMapInArchive( Archive, mapName ) )
- {
- return;
- }
- }
-
- Q3BSPFileParser fileParser( mapName, &Archive );
- Q3BSPModel *pBSPModel = fileParser.getModel();
- if ( NULL != pBSPModel )
- {
- CreateDataFromImport( pBSPModel, pScene, &Archive );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Separates the map name from the import name.
-void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName,
- std::string &rMapName )
-{
- rArchiveName = "";
- rMapName = "";
- if ( rImportName.empty() )
- return;
-
- std::string::size_type pos = rImportName.rfind( "," );
- if ( std::string::npos == pos )
- {
- rArchiveName = rImportName;
- return;
- }
-
- rArchiveName = rImportName.substr( 0, pos );
- rMapName = rImportName.substr( pos, rImportName.size() - pos - 1 );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the first map in the map archive.
-bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName )
-{
- rMapName = "";
- std::vector<std::string> fileList;
- rArchive.getFileList( fileList );
- if ( fileList.empty() )
- return false;
-
- for ( std::vector<std::string>::iterator it = fileList.begin(); it != fileList.end();
- ++it )
- {
- std::string::size_type pos = (*it).find( "maps/" );
- if ( std::string::npos != pos )
- {
- std::string::size_type extPos = (*it).find( ".bsp" );
- if ( std::string::npos != extPos )
- {
- rMapName = *it;
- return true;
- }
- }
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the assimp specific data.
-void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- Q3BSPZipArchive *pArchive )
-{
- if ( NULL == pModel || NULL == pScene )
- return;
-
- pScene->mRootNode = new aiNode;
- if ( !pModel->m_ModelName.empty() )
- {
- pScene->mRootNode->mName.Set( pModel->m_ModelName );
- }
-
- // Create the face to material relation map
- createMaterialMap( pModel );
-
- // Create all nodes
- CreateNodes( pModel, pScene, pScene->mRootNode );
-
- // Create the assigned materials
- createMaterials( pModel, pScene, pArchive );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all assimp nodes.
-void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- aiNode *pParent )
-{
- ai_assert( NULL != pModel );
- if ( NULL == pModel )
- {
- return;
- }
-
- unsigned int matIdx = 0;
- std::vector<aiMesh*> MeshArray;
- std::vector<aiNode*> NodeArray;
- for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it )
- {
- std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
- size_t numVerts = countData( *pArray );
- if ( 0 != numVerts )
- {
- aiMesh* pMesh = new aiMesh;
- aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, pMesh );
- if ( NULL != pNode )
- {
- NodeArray.push_back( pNode );
- MeshArray.push_back( pMesh );
- }
- else
- {
- delete pMesh;
- }
- }
- matIdx++;
- }
-
- pScene->mNumMeshes = MeshArray.size();
- if ( pScene->mNumMeshes > 0 )
- {
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
- for ( size_t i = 0; i < MeshArray.size(); i++ )
- {
- aiMesh *pMesh = MeshArray[ i ];
- if ( NULL != pMesh )
- {
- pScene->mMeshes[ i ] = pMesh;
- }
- }
- }
-
- pParent->mNumChildren = MeshArray.size();
- pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
- for ( size_t i=0; i<NodeArray.size(); i++ )
- {
- aiNode *pNode = NodeArray[ i ];
- pNode->mParent = pParent;
- pParent->mChildren[ i ] = pNode;
- pParent->mChildren[ i ]->mMeshes[ 0 ] = i;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the topology.
-aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel,
- unsigned int materialIdx,
- std::vector<sQ3BSPFace*> &rArray,
- aiMesh* pMesh )
-{
- size_t numVerts = countData( rArray );
- if ( 0 == numVerts )
- {
- return NULL;
- }
-
- size_t numFaces = countFaces( rArray );
- if ( 0 == numFaces )
- {
- return NULL;
- }
-
- size_t numTriangles = countTriangles( rArray );
- pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pMesh->mFaces = new aiFace[ numTriangles ];
- pMesh->mNumFaces = numTriangles;
-
- pMesh->mNumVertices = numVerts;
- pMesh->mVertices = new aiVector3D[ numVerts ];
- pMesh->mNormals = new aiVector3D[ numVerts ];
- pMesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ];
- pMesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ];
- pMesh->mMaterialIndex = materialIdx;
-
- unsigned int faceIdx = 0;
- unsigned int vertIdx = 0;
- pMesh->mNumUVComponents[ 0 ] = 2;
- pMesh->mNumUVComponents[ 1 ] = 2;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- ai_assert( NULL != pQ3BSPFace );
- if ( NULL == pQ3BSPFace )
- {
- continue;
- }
-
- if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
- {
- if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
- {
- createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx );
- }
- }
- }
-
- aiNode *pNode = new aiNode;
- pNode->mNumMeshes = 1;
- pNode->mMeshes = new unsigned int[ 1 ];
-
- return pNode;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the triangle topology from a face array.
-void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
- Q3BSP::sQ3BSPFace *pQ3BSPFace,
- aiMesh* pMesh,
- unsigned int &rFaceIdx,
- unsigned int &rVertIdx )
-{
- ai_assert( rFaceIdx < pMesh->mNumFaces );
-
- m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
- ai_assert( NULL != m_pCurrentFace );
- if ( NULL == m_pCurrentFace )
- {
- return;
- }
-
- m_pCurrentFace->mNumIndices = 3;
- m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ];
-
- size_t idx = 0;
- for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; i++ )
- {
- const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ];
- ai_assert( index < pModel->m_Vertices.size() );
- if ( index >= pModel->m_Vertices.size() )
- {
- continue;
- }
-
- sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ];
- ai_assert( NULL != pVertex );
- if ( NULL == pVertex )
- {
- continue;
- }
-
- pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
- pMesh->mNormals[ rVertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z );
-
- pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
- pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
-
- m_pCurrentFace->mIndices[ idx ] = rVertIdx;
- rVertIdx++;
-
- idx++;
- if ( idx > 2 )
- {
- idx = 0;
- m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
- if ( NULL != m_pCurrentFace )
- {
- m_pCurrentFace->mNumIndices = 3;
- m_pCurrentFace->mIndices = new unsigned int[ 3 ];
- }
- }
- }
- rFaceIdx--;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all referenced materials.
-void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- Q3BSPZipArchive *pArchive )
-{
- if ( m_MaterialLookupMap.empty() )
- {
- return;
- }
-
- pScene->mMaterials = new aiMaterial*[ m_MaterialLookupMap.size() ];
- // size_t texIdx( 0 );
- aiString aiMatName;
- int textureId( -1 ), lightmapId( -1 );
- for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
- ++it )
- {
- const std::string matName = (*it).first;
- if ( matName.empty() )
- {
- continue;
- }
-
- aiMatName.Set( matName );
- Assimp::MaterialHelper *pMatHelper = new Assimp::MaterialHelper;
- pMatHelper->AddProperty( &aiMatName, AI_MATKEY_NAME );
-
- extractIds( matName, textureId, lightmapId );
-
- // Adding the texture
- if ( -1 != textureId )
- {
- sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
- if ( NULL != pTexture )
- {
- std::string tmp( "*" ), texName( "" );
- tmp += pTexture->strName;
- tmp += ".jpg";
- normalizePathName( tmp, texName );
-
- if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) )
- {
- }
- }
-
- }
- if ( -1 != lightmapId )
- {
- importLightmap( pModel, pScene, pMatHelper, lightmapId );
- }
- pScene->mMaterials[ pScene->mNumMaterials ] = pMatHelper;
- pScene->mNumMaterials++;
- }
- pScene->mNumTextures = mTextures.size();
- pScene->mTextures = new aiTexture*[ pScene->mNumTextures ];
- std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts the number of referenced vertices.
-size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &rArray ) const
-{
- size_t numVerts = 0;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- sQ3BSPFace *pQ3BSPFace = *it;
- if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- ai_assert( NULL != pQ3BSPFace );
- numVerts += pQ3BSPFace->iNumOfFaceVerts;
- }
- }
-
- return numVerts;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts the faces with vertices.
-size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
-{
- size_t numFaces = 0;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
- {
- numFaces++;
- }
- }
-
- return numFaces;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts the number of triangles in a Q3-facearray.
-size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
-{
- size_t numTriangles = 0;
- for ( std::vector<Q3BSP::sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- if ( NULL != pQ3BSPFace )
- {
- numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3;
- }
- }
-
- return numTriangles;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the faces-to-material map.
-void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
-{
- std::string key( "" );
- std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
- for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[ idx ];
- const int texId = pQ3BSPFace->iTextureID;
- const int lightMapId = pQ3BSPFace->iLightmapID;
- createKey( texId, lightMapId, key );
- FaceMapIt it = m_MaterialLookupMap.find( key );
- if ( m_MaterialLookupMap.end() == it )
- {
- pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>;
- m_MaterialLookupMap[ key ] = pCurFaceArray;
- }
- else
- {
- pCurFaceArray = (*it).second;
- }
- ai_assert( NULL != pCurFaceArray );
- if ( NULL != pCurFaceArray )
- {
- pCurFaceArray->push_back( pQ3BSPFace );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the next face.
-aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx )
-{
- aiFace *pFace = NULL;
- if ( rFaceIdx < pMesh->mNumFaces )
- {
- pFace = &pMesh->mFaces[ rFaceIdx ];
- rFaceIdx++;
- }
- else
- {
- pFace = NULL;
- }
-
- return pFace;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports a texture file.
-bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel,
- Q3BSP::Q3BSPZipArchive *pArchive, aiScene* /*pScene*/,
- Assimp::MaterialHelper *pMatHelper, int textureId )
-{
- if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper )
- {
- return false;
- }
-
- if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) )
- {
- return false;
- }
-
- bool res = true;
- sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
- if ( NULL == pTexture )
- return false;
-
- std::string textureName = pTexture->strName;
- textureName += ".jpg";
- if ( pArchive->Exists( textureName.c_str() ) )
- {
- IOStream *pTextureStream = pArchive->Open( textureName.c_str() );
- if ( NULL != pTextureStream )
- {
- size_t texSize = pTextureStream->FileSize();
- aiTexture *pTexture = new aiTexture;
- pTexture->mHeight = 0;
- pTexture->mWidth = texSize;
- unsigned char *pData = new unsigned char[ pTexture->mWidth ];
- size_t readSize = pTextureStream->Read( pData, sizeof( unsigned char ), pTexture->mWidth );
- ai_assert( readSize == pTexture->mWidth );
- pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
- pTexture->achFormatHint[ 0 ] = 'j';
- pTexture->achFormatHint[ 1 ] = 'p';
- pTexture->achFormatHint[ 2 ] = 'g';
- pTexture->achFormatHint[ 2 ] = '\0';
- res = true;
-
- aiString name;
- name.data[ 0 ] = '*';
- name.length = 1 + ASSIMP_itoa10( name.data + 1, MAXLEN-1, mTextures.size() );
-
- pArchive->Close( pTextureStream );
-
- pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
- mTextures.push_back( pTexture );
- }
- }
-
- return res;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports a lightmap file.
-bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- Assimp::MaterialHelper *pMatHelper, int lightmapId )
-{
- if ( NULL == pModel || NULL == pScene || NULL == pMatHelper )
- {
- return false;
- }
-
- if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) )
- {
- return false;
- }
-
- sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ];
- if ( NULL == pLightMap )
- {
- return false;
- }
-
- aiTexture *pTexture = new aiTexture;
- pTexture->mHeight = 0;
- pTexture->mWidth = CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT;
-
- unsigned char *pData = new unsigned char[ pTexture->mWidth ];
- pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
-
- pTexture->achFormatHint[ 0 ] = 'b';
- pTexture->achFormatHint[ 1 ] = 'm';
- pTexture->achFormatHint[ 2 ] = 'p';
- pTexture->achFormatHint[ 3 ] = '\0';
-
- memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth );
-
- aiString name;
- name.data[ 0 ] = '*';
- name.length = 1 + ASSIMP_itoa10( name.data + 1, MAXLEN-1, mTextures.size() );
-
- pMatHelper->AddProperty( &name,AI_MATKEY_TEXTURE_LIGHTMAP( 1 ) );
- mTextures.push_back( pTexture );
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
diff --git a/3rdparty/assimp/code/Q3BSPFileImporter.h b/3rdparty/assimp/code/Q3BSPFileImporter.h
deleted file mode 100644
index adf79e64..00000000
--- a/3rdparty/assimp/code/Q3BSPFileImporter.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#ifndef ASSIMP_Q3BSPFILEIMPORTER_H_INC
-#define ASSIMP_Q3BSPFILEIMPORTER_H_INC
-
-#include "BaseImporter.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-class Q3BSPZipArchive;
-struct Q3BSPModel;
-struct sQ3BSPFace;
-
-}
-
-/** Loader to import BSP-levels from a PK3 archive or from a unpacked BSP-level.
- */
-class Q3BSPFileImporter : BaseImporter
-{
- friend class Importer;
-
-protected:
- /// @brief Default constructor.
- Q3BSPFileImporter();
-
- /// @brief Destructor.
- ~Q3BSPFileImporter();
-
-public:
- /// @brief Returns whether the class can handle the format of the given file.
- /// @remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
-
-private:
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*> FaceMap;
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt;
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt;
-
- void GetExtensionList(std::set<std::string>& extensions);
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
- void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );
- bool findFirstMapInArchive( Q3BSP::Q3BSPZipArchive &rArchive, std::string &rMapName );
- void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
- void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent );
- aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx,
- std::vector<Q3BSP::sQ3BSPFace*> &rArray, aiMesh* pMesh );
- void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx,
- unsigned int &rVertIdx );
- void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
- size_t countData( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- size_t countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- size_t countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- void createMaterialMap( const Q3BSP::Q3BSPModel *pModel);
- aiFace *getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx );
- bool importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, Q3BSP::Q3BSPZipArchive *pArchive, aiScene* pScene,
- Assimp::MaterialHelper *pMatHelper, int textureId );
- bool importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Assimp::MaterialHelper *pMatHelper, int lightmapId );
-
-private:
- aiMesh *m_pCurrentMesh;
- aiFace *m_pCurrentFace;
- FaceMap m_MaterialLookupMap;
- std::vector<aiTexture*> mTextures;
-};
-
-} // Namespace Assimp
-
-#endif // ASSIMP_Q3BSPFILEIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/Q3BSPFileParser.cpp b/3rdparty/assimp/code/Q3BSPFileParser.cpp
deleted file mode 100644
index 09411ca5..00000000
--- a/3rdparty/assimp/code/Q3BSPFileParser.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#include "AssimpPCH.h"
-#include "Q3BSPFileParser.h"
-#include "DefaultIOSystem.h"
-#include "Q3BSPFileData.h"
-#include "Q3BSPZipArchive.h"
-#include <vector>
-
-namespace Assimp
-{
-
-using namespace Q3BSP;
-
-// ------------------------------------------------------------------------------------------------
-Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, Q3BSPZipArchive *pZipArchive ) :
- m_sOffset( 0 ),
- m_Data(),
- m_pModel( NULL ),
- m_pZipArchive( pZipArchive )
-{
- ai_assert( NULL != m_pZipArchive );
- ai_assert( !rMapName.empty() );
-
- if ( !readData( rMapName ) )
- return;
-
- m_pModel = new Q3BSPModel;
- m_pModel->m_ModelName = rMapName;
- if ( !parseFile() )
- {
- delete m_pModel;
- m_pModel = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-Q3BSPFileParser::~Q3BSPFileParser()
-{
- delete m_pModel;
- m_pModel = NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const
-{
- return m_pModel;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::readData( const std::string &rMapName )
-{
- if ( !m_pZipArchive->Exists( rMapName.c_str() ) )
- return false;
-
- IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() );
- if ( NULL == pMapFile )
- return false;
-
- const size_t size = pMapFile->FileSize();
- m_Data.resize( size );
-
- const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
- if ( readSize != size )
- {
- m_Data.clear();
- return false;
- }
- m_pZipArchive->Close( pMapFile );
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::parseFile()
-{
- if ( m_Data.empty() )
- {
- return false;
- }
-
- if ( !validateFormat() )
- {
- return false;
- }
-
- // Imports the dictionary of the level
- getLumps();
-
- // Conunt data and prepare model data
- countLumps();
-
- // Read in Vertices
- getVertices();
-
- // Read in Indices
- getIndices();
-
- // Read Faces
- getFaces();
-
- // Read Textures
- getTextures();
-
- // Read Lightmaps
- getLightMaps();
-
- // Load the entities
- getEntities();
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::validateFormat()
-{
- sQ3BSPHeader *pHeader = (sQ3BSPHeader*) &m_Data[ 0 ];
- m_sOffset += sizeof( sQ3BSPHeader );
-
- // Version and identify string validation
- if (pHeader->strID[ 0 ] != 'I' || pHeader->strID[ 1 ] != 'B' || pHeader->strID[ 2 ] != 'S'
- || pHeader->strID[ 3 ] != 'P')
- {
- return false;
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getLumps()
-{
- size_t Offset = m_sOffset;
- m_pModel->m_Lumps.resize( kMaxLumps );
- for ( size_t idx=0; idx < kMaxLumps; idx++ )
- {
- sQ3BSPLump *pLump = new sQ3BSPLump;
- memcpy( pLump, &m_Data[ Offset ], sizeof( sQ3BSPLump ) );
- Offset += sizeof( sQ3BSPLump );
- m_pModel->m_Lumps[ idx ] = pLump;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::countLumps()
-{
- m_pModel->m_Vertices.resize( m_pModel->m_Lumps[ kVertices ]->iSize / sizeof( sQ3BSPVertex ) );
- m_pModel->m_Indices.resize( m_pModel->m_Lumps[ kMeshVerts ]->iSize / sizeof( int ) );
- m_pModel->m_Faces.resize( m_pModel->m_Lumps[ kFaces ]->iSize / sizeof( sQ3BSPFace ) );
- m_pModel->m_Textures.resize( m_pModel->m_Lumps[ kTextures ]->iSize / sizeof( sQ3BSPTexture ) );
- m_pModel->m_Lightmaps.resize( m_pModel->m_Lumps[ kLightmaps ]->iSize / sizeof( sQ3BSPLightmap ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getVertices()
-{
- size_t Offset = m_pModel->m_Lumps[ kVertices ]->iOffset;
- for ( size_t idx = 0; idx < m_pModel->m_Vertices.size(); idx++ )
- {
- sQ3BSPVertex *pVertex = new sQ3BSPVertex;
- memcpy( pVertex, &m_Data[ Offset ], sizeof( sQ3BSPVertex ) );
- Offset += sizeof( sQ3BSPVertex );
- m_pModel->m_Vertices[ idx ] = pVertex;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getIndices()
-{
- ai_assert( NULL != m_pModel );
-
- sQ3BSPLump *lump = m_pModel->m_Lumps[ kMeshVerts ];
- size_t Offset = (size_t) lump->iOffset;
- const size_t nIndices = lump->iSize / sizeof( int );
- m_pModel->m_Indices.resize( nIndices );
- memcpy( &m_pModel->m_Indices[ 0 ], &m_Data[ Offset ], lump->iSize );
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getFaces()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[ kFaces ]->iOffset;
- for ( size_t idx = 0; idx < m_pModel->m_Faces.size(); idx++ )
- {
- sQ3BSPFace *pFace = new sQ3BSPFace;
- memcpy( pFace, &m_Data[ Offset ], sizeof( sQ3BSPFace ) );
- m_pModel->m_Faces[ idx ] = pFace;
- Offset += sizeof( sQ3BSPFace );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getTextures()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[ kTextures ]->iOffset;
- for ( size_t idx=0; idx < m_pModel->m_Textures.size(); idx++ )
- {
- sQ3BSPTexture *pTexture = new sQ3BSPTexture;
- memcpy( pTexture, &m_Data[ Offset ], sizeof(sQ3BSPTexture) );
- m_pModel->m_Textures[ idx ] = pTexture;
- Offset += sizeof(sQ3BSPTexture);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getLightMaps()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[kLightmaps]->iOffset;
- for ( size_t idx=0; idx < m_pModel->m_Lightmaps.size(); idx++ )
- {
- sQ3BSPLightmap *pLightmap = new sQ3BSPLightmap;
- memcpy( pLightmap, &m_Data[ Offset ], sizeof( sQ3BSPLightmap ) );
- Offset += sizeof( sQ3BSPLightmap );
- m_pModel->m_Lightmaps[ idx ] = pLightmap;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getEntities()
-{
- int size = m_pModel->m_Lumps[ kEntities ]->iSize;
- m_pModel->m_EntityData.resize( size );
- size_t Offset = m_pModel->m_Lumps[ kEntities ]->iOffset;
- memcpy( &m_pModel->m_EntityData[ 0 ], &m_Data[ Offset ], sizeof( char ) * size );
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
diff --git a/3rdparty/assimp/code/Q3BSPFileParser.h b/3rdparty/assimp/code/Q3BSPFileParser.h
deleted file mode 100644
index a049dc29..00000000
--- a/3rdparty/assimp/code/Q3BSPFileParser.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef ASSIMP_Q3BSPFILEPARSER_H_INC
-#define ASSIMP_Q3BSPFILEPARSER_H_INC
-
-#include "BaseImporter.h"
-#include <string>
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-class Q3BSPZipArchive;
-struct Q3BSPModel;
-class ZipFile;
-
-}
-
-// -------------------------------------------------------------------
-// -------------------------------------------------------------------
-class Q3BSPFileParser
-{
-public:
- Q3BSPFileParser( const std::string &rMapName, Q3BSP::Q3BSPZipArchive *pZipArchive );
- ~Q3BSPFileParser();
- Q3BSP::Q3BSPModel *getModel() const;
-
-protected:
- bool readData(const std::string &rMapName);
- bool parseFile();
- bool validateFormat();
- void getLumps();
- void countLumps();
- void getVertices();
- void getIndices();
- void getFaces();
- void getTextures();
- void getLightMaps();
- void getEntities();
-
-private:
- size_t m_sOffset;
- std::vector<char> m_Data;
- Q3BSP::Q3BSPModel *m_pModel;
- Q3BSP::Q3BSPZipArchive *m_pZipArchive;
-};
-
-} // Namespace Assimp
-
-#endif // ASSIMP_Q3BSPFILEPARSER_H_INC
diff --git a/3rdparty/assimp/code/Q3BSPZipArchive.cpp b/3rdparty/assimp/code/Q3BSPZipArchive.cpp
deleted file mode 100644
index 62ef5ffc..00000000
--- a/3rdparty/assimp/code/Q3BSPZipArchive.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#include "Q3BSPZipArchive.h"
-#include <algorithm>
-#include <cassert>
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) :
- m_ZipFileHandle( NULL ),
- m_FileList(),
- m_bDirty( true )
-{
- if ( !rFile.empty() )
- {
- m_ZipFileHandle = unzOpen( rFile.c_str() );
- if ( NULL != m_ZipFileHandle )
- {
- mapArchive();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-Q3BSPZipArchive::~Q3BSPZipArchive()
-{
- if ( NULL != m_ZipFileHandle )
- {
- unzClose( m_ZipFileHandle );
- }
- m_ZipFileHandle = NULL;
- m_FileList.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the archive is already open.
-bool Q3BSPZipArchive::isOpen() const
-{
- return ( NULL != m_ZipFileHandle );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the filename is part of the archive.
-bool Q3BSPZipArchive::Exists( const char* pFile ) const
-{
- ai_assert( NULL != pFile );
- if ( NULL == pFile )
- {
- return false;
- }
-
- std::string rFile( pFile );
- std::vector<std::string>::const_iterator it = std::find( m_FileList.begin(), m_FileList.end(), rFile );
- if ( m_FileList.end() == it )
- {
- return false;
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the separator delimiter.
-char Q3BSPZipArchive::getOsSeparator() const
-{
- return '/';
-}
-
-// ------------------------------------------------------------------------------------------------
-// Opens a file, which is part of the archive.
-IOStream *Q3BSPZipArchive::Open( const char* pFile, const char* /*pMode*/ )
-{
- ai_assert( NULL != pFile );
-
- std::string rItem( pFile );
- std::vector<std::string>::iterator it = std::find( m_FileList.begin(), m_FileList.end(), rItem );
- if ( m_FileList.end() == it )
- return NULL;
-
- ZipFile *pZipFile = new ZipFile( *it, m_ZipFileHandle );
- m_ArchiveMap[ rItem ] = pZipFile;
-
- return pZipFile;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Close a filestream.
-void Q3BSPZipArchive::Close( IOStream *pFile )
-{
- ai_assert( NULL != pFile );
-
- std::map<std::string, IOStream*>::iterator it;
- for ( it = m_ArchiveMap.begin(); it != m_ArchiveMap.end(); ++it )
- {
- if ( (*it).second == pFile )
- {
- ZipFile *pZipFile = reinterpret_cast<ZipFile*>( (*it).second );
- delete pZipFile;
- m_ArchiveMap.erase( it );
- break;
- }
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Returns the file-list of the archive.
-void Q3BSPZipArchive::getFileList( std::vector<std::string> &rFileList )
-{
- rFileList = m_FileList;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Maps the archive content.
-bool Q3BSPZipArchive::mapArchive()
-{
- if ( NULL == m_ZipFileHandle )
- return false;
-
- if ( !m_bDirty )
- return true;
-
- if ( !m_FileList.empty() )
- m_FileList.resize( 0 );
-
- // At first ensure file is already open
- if ( UNZ_OK == unzGoToFirstFile( m_ZipFileHandle ) )
- {
- char filename[ FileNameSize ];
- unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 );
- m_FileList.push_back( filename );
- unzCloseCurrentFile( m_ZipFileHandle );
-
- // Loop over all files
- while ( unzGoToNextFile( m_ZipFileHandle ) != UNZ_END_OF_LIST_OF_FILE )
- {
- char filename[ FileNameSize ];
- unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 );
- m_FileList.push_back( filename );
- unzCloseCurrentFile( m_ZipFileHandle );
- }
- }
-
- std::sort( m_FileList.begin(), m_FileList.end() );
- m_bDirty = false;
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Q3BSP
-} // Namespace Assimp
diff --git a/3rdparty/assimp/code/Q3BSPZipArchive.h b/3rdparty/assimp/code/Q3BSPZipArchive.h
deleted file mode 100644
index c0d8b96c..00000000
--- a/3rdparty/assimp/code/Q3BSPZipArchive.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#ifndef AI_Q3BSP_ZIPARCHIVE_H_INC
-#define AI_Q3BSP_ZIPARCHIVE_H_INC
-
-#include "../contrib/unzip/unzip.h"
-#include "../include/IOStream.h"
-#include "../include/IOSystem.h"
-#include <string>
-#include <vector>
-#include <map>
-#include <cassert>
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-// ------------------------------------------------------------------------------------------------
-/// \class ZipFile
-/// \ingroup Assimp::Q3BSP
-///
-/// \brief
-// ------------------------------------------------------------------------------------------------
-class ZipFile : public IOStream
-{
-public:
- ZipFile( const std::string &rFileName, unzFile zipFile ) :
- m_Name( rFileName ),
- m_zipFile( zipFile )
- {
- ai_assert( NULL != m_zipFile );
- }
-
- ~ZipFile()
- {
- m_zipFile = NULL;
- }
-
- size_t Read(void* pvBuffer, size_t pSize, size_t pCount )
- {
- size_t bytes_read = 0;
- if ( NULL == m_zipFile )
- return bytes_read;
-
- // search file and place file pointer there
- if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK )
- {
- // get file size, etc.
- unz_file_info fileInfo;
- unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
- const size_t size = pSize * pCount;
- assert( size <= fileInfo.uncompressed_size );
-
- // The file has EXACTLY the size of uncompressed_size. In C
- // you need to mark the last character with '\0', so add
- // another character
- unzOpenCurrentFile( m_zipFile );
- bytes_read = unzReadCurrentFile( m_zipFile, pvBuffer, fileInfo.uncompressed_size);
- if ( /*bytes_read < 0 ||*/ bytes_read != static_cast<size_t>( fileInfo.uncompressed_size ) )
- {
- return 0;
- }
- //size_t filesize = fileInfo.uncompressed_size;
- unzCloseCurrentFile( m_zipFile );
- }
- return bytes_read;
- }
-
- size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/)
- {
- return 0;
- }
-
- size_t FileSize() const
- {
- if ( NULL == m_zipFile )
- return 0;
- if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK )
- {
- unz_file_info fileInfo;
- unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
- return fileInfo.uncompressed_size;
- }
- return 0;
- }
-
- aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/)
- {
- return aiReturn_FAILURE;
- }
-
- size_t Tell() const
- {
- return 0;
- }
-
- void Flush()
- {
- // empty
- }
-
-private:
- std::string m_Name;
- unzFile m_zipFile;
-};
-
-// ------------------------------------------------------------------------------------------------
-/// \class Q3BSPZipArchive
-/// \ingroup Assimp::Q3BSP
-///
-/// \brief IMplements a zip archive like the WinZip archives. Will be also used to import data
-/// from a P3K archive ( Quake level format ).
-// ------------------------------------------------------------------------------------------------
-class Q3BSPZipArchive : public Assimp::IOSystem
-{
-public:
- static const unsigned int FileNameSize = 256;
-
-public:
- Q3BSPZipArchive( const std::string & rFile );
- ~Q3BSPZipArchive();
- bool Exists( const char* pFile) const;
- char getOsSeparator() const;
- IOStream* Open(const char* pFile, const char* pMode = "rb");
- void Close( IOStream* pFile);
- bool isOpen() const;
- void getFileList( std::vector<std::string> &rFileList );
-
-private:
- bool mapArchive();
-
-private:
- unzFile m_ZipFileHandle;
- std::map<std::string, IOStream*> m_ArchiveMap;
- std::vector<std::string> m_FileList;
- bool m_bDirty;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Q3BSP
-} // Namespace Assimp
-
-#endif // AI_Q3BSP_ZIPARCHIVE_H_INC
diff --git a/3rdparty/assimp/code/Q3DLoader.cpp b/3rdparty/assimp/code/Q3DLoader.cpp
deleted file mode 100644
index aaba431c..00000000
--- a/3rdparty/assimp/code/Q3DLoader.cpp
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Q3DLoader.cpp
- * @brief Implementation of the Q3D importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-
-// internal headers
-#include "Q3DLoader.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-Q3DImporter::Q3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Q3DImporter::~Q3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "q3s" || extension == "q3o")
- return true;
- else if (!extension.length() || checkSig) {
- if (!pIOHandler)
- return true;
- const char* tokens[] = {"quick3Do","quick3Ds"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3DImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("q3o");
- extensions.insert("q3s");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void Q3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
-
- // The header is 22 bytes large
- if (stream.GetRemainingSize() < 22)
- throw DeadlyImportError("File is either empty or corrupt: " + pFile);
-
- // Check the file's signature
- if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) &&
- ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 ))
- {
- throw DeadlyImportError("Not a Quick3D file. Signature string is: " +
- std::string((const char*)stream.GetPtr(),8));
- }
-
- // Print the file format version
- DefaultLogger::get()->info("Quick3D File format version: " +
- std::string(&((const char*)stream.GetPtr())[8],2));
-
- // ... an store it
- char major = ((const char*)stream.GetPtr())[8];
- char minor = ((const char*)stream.GetPtr())[9];
-
- stream.IncPtr(10);
- unsigned int numMeshes = (unsigned int)stream.GetI4();
- unsigned int numMats = (unsigned int)stream.GetI4();
- unsigned int numTextures = (unsigned int)stream.GetI4();
-
- std::vector<Material> materials;
- materials.reserve(numMats);
-
- std::vector<Mesh> meshes;
- meshes.reserve(numMeshes);
-
- // Allocate the scene root node
- pScene->mRootNode = new aiNode();
-
- aiColor3D fgColor (0.6f,0.6f,0.6f);
-
- // Now read all file chunks
- while (true)
- {
- if (stream.GetRemainingSize() < 1)break;
- char c = stream.GetI1();
- switch (c)
- {
- // Meshes chunk
- case 'm':
- {
- for (unsigned int quak = 0; quak < numMeshes; ++quak)
- {
- meshes.push_back(Mesh());
- Mesh& mesh = meshes.back();
-
- // read all vertices
- unsigned int numVerts = (unsigned int)stream.GetI4();
- if (!numVerts)
- throw DeadlyImportError("Quick3D: Found mesh with zero vertices");
-
- std::vector<aiVector3D>& verts = mesh.verts;
- verts.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- verts[i].x = stream.GetF4();
- verts[i].y = stream.GetF4();
- verts[i].z = stream.GetF4();
- }
-
- // read all faces
- numVerts = (unsigned int)stream.GetI4();
- if (!numVerts)
- throw DeadlyImportError("Quick3D: Found mesh with zero faces");
-
- std::vector<Face >& faces = mesh.faces;
- faces.reserve(numVerts);
-
- // number of indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- faces.push_back(Face(stream.GetI2()) );
- if (faces.back().indices.empty())
- throw DeadlyImportError("Quick3D: Found face with zero indices");
- }
-
- // indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- Face& vec = faces[i];
- for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
- vec.indices[a] = stream.GetI4();
- }
-
- // material indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- faces[i].mat = (unsigned int)stream.GetI4();
- }
-
- // read all normals
- numVerts = (unsigned int)stream.GetI4();
- std::vector<aiVector3D>& normals = mesh.normals;
- normals.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- normals[i].x = stream.GetF4();
- normals[i].y = stream.GetF4();
- normals[i].z = stream.GetF4();
- }
-
- numVerts = (unsigned int)stream.GetI4();
- if (numTextures && numVerts)
- {
- // read all texture coordinates
- std::vector<aiVector3D>& uv = mesh.uv;
- uv.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- uv[i].x = stream.GetF4();
- uv[i].y = stream.GetF4();
- }
-
- // UV indices
- for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
- {
- Face& vec = faces[i];
- for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
- {
- vec.uvindices[a] = stream.GetI4();
- if (!i && !a)
- mesh.prevUVIdx = vec.uvindices[a];
- else if (vec.uvindices[a] != mesh.prevUVIdx)
- mesh.prevUVIdx = 0xffffffff;
- }
- }
- }
-
- // we don't need the rest, but we need to get to the next chunk
- stream.IncPtr(36);
- if (minor > '0' && major == '3')
- stream.IncPtr(mesh.faces.size());
- }
- // stream.IncPtr(4); // unknown value here
- }
- break;
-
- // materials chunk
- case 'c':
-
- for (unsigned int i = 0; i < numMats; ++i)
- {
- materials.push_back(Material());
- Material& mat = materials.back();
-
- // read the material name
- while (( c = stream.GetI1()))
- mat.name.data[mat.name.length++] = c;
-
- // add the terminal character
- mat.name.data[mat.name.length] = '\0';
-
- // read the ambient color
- mat.ambient.r = stream.GetF4();
- mat.ambient.g = stream.GetF4();
- mat.ambient.b = stream.GetF4();
-
- // read the diffuse color
- mat.diffuse.r = stream.GetF4();
- mat.diffuse.g = stream.GetF4();
- mat.diffuse.b = stream.GetF4();
-
- // read the ambient color
- mat.specular.r = stream.GetF4();
- mat.specular.g = stream.GetF4();
- mat.specular.b = stream.GetF4();
-
- // read the transparency
- mat.transparency = stream.GetF4();
-
- // unknown value here
- // stream.IncPtr(4);
- // FIX: it could be the texture index ...
- mat.texIdx = (unsigned int)stream.GetI4();
- }
-
- break;
-
- // texture chunk
- case 't':
-
- pScene->mNumTextures = numTextures;
- if (!numTextures)break;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures];
- // to make sure we won't crash if we leave through an exception
- ::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures);
- for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
- {
- aiTexture* tex = pScene->mTextures[i] = new aiTexture();
-
- // skip the texture name
- while (stream.GetI1()) {};
-
- // read texture width and height
- tex->mWidth = (unsigned int)stream.GetI4();
- tex->mHeight = (unsigned int)stream.GetI4();
-
- if (!tex->mWidth || !tex->mHeight)
- throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
-
- register unsigned int mul = tex->mWidth * tex->mHeight;
- aiTexel* begin = tex->pcData = new aiTexel[mul];
- aiTexel* const end = & begin [mul];
-
- for (;begin != end; ++begin)
- {
- begin->r = stream.GetI1();
- begin->g = stream.GetI1();
- begin->b = stream.GetI1();
- begin->a = 0xff;
- }
- }
-
- break;
-
- // scene chunk
- case 's':
- {
- // skip position and rotation
- stream.IncPtr(12);
-
- for (unsigned int i = 0; i < 4;++i)
- for (unsigned int a = 0; a < 4;++a)
- pScene->mRootNode->mTransformation[i][a] = stream.GetF4();
-
- stream.IncPtr(16);
-
- // now setup a single camera
- pScene->mNumCameras = 1;
- pScene->mCameras = new aiCamera*[1];
- aiCamera* cam = pScene->mCameras[0] = new aiCamera();
- cam->mPosition.x = stream.GetF4();
- cam->mPosition.y = stream.GetF4();
- cam->mPosition.z = stream.GetF4();
- cam->mName.Set("Q3DCamera");
-
- // skip eye rotation for the moment
- stream.IncPtr(12);
-
- // read the default material color
- fgColor .r = stream.GetF4();
- fgColor .g = stream.GetF4();
- fgColor .b = stream.GetF4();
-
- // skip some unimportant properties
- stream.IncPtr(29);
-
- // setup a single point light with no attenuation
- pScene->mNumLights = 1;
- pScene->mLights = new aiLight*[1];
- aiLight* light = pScene->mLights[0] = new aiLight();
- light->mName.Set("Q3DLight");
- light->mType = aiLightSource_POINT;
-
- light->mAttenuationConstant = 1;
- light->mAttenuationLinear = 0;
- light->mAttenuationQuadratic = 0;
-
- light->mColorDiffuse.r = stream.GetF4();
- light->mColorDiffuse.g = stream.GetF4();
- light->mColorDiffuse.b = stream.GetF4();
-
- light->mColorSpecular = light->mColorDiffuse;
-
-
- // We don't need the rest, but we need to know where
- // this fucking chunk ends.
- unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
-
- // skip the background file name
- while (stream.GetI1()) {};
-
- // skip background texture data + the remaining fields
- stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here
-
- // TODO
- goto outer;
- }
- break;
-
- default:
- throw DeadlyImportError("Quick3D: Unknown chunk");
- break;
- };
- }
-outer:
-
- // If we have no mesh loaded - break here
- if (meshes.empty())
- throw DeadlyImportError("Quick3D: No meshes loaded");
-
- // If we have no materials loaded - generate a default mat
- if (materials.empty())
- {
- DefaultLogger::get()->info("Quick3D: No material found, generating one");
- materials.push_back(Material());
- materials.back().diffuse = fgColor ;
- }
-
- // find out which materials we'll need
- typedef std::pair<unsigned int, unsigned int> FaceIdx;
- typedef std::vector< FaceIdx > FaceIdxArray;
- FaceIdxArray* fidx = new FaceIdxArray[materials.size()];
-
- unsigned int p = 0;
- for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
- it != end; ++it,++p)
- {
- unsigned int q = 0;
- for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
- fit != fend; ++fit,++q)
- {
- if ((*fit).mat >= materials.size())
- {
- DefaultLogger::get()->warn("Quick3D: Material index overflow");
- (*fit).mat = 0;
- }
- if (fidx[(*fit).mat].empty())++pScene->mNumMeshes;
- fidx[(*fit).mat].push_back( FaceIdx(p,q) );
- }
- }
- pScene->mNumMaterials = pScene->mNumMeshes;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- pScene->mMeshes = new aiMesh*[pScene->mNumMaterials];
-
- for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i)
- {
- if (fidx[i].empty())continue;
-
- // Allocate a mesh and a material
- aiMesh* mesh = pScene->mMeshes[real] = new aiMesh();
- MaterialHelper* mat = new MaterialHelper();
- pScene->mMaterials[real] = mat;
-
- mesh->mMaterialIndex = real;
-
- // Build the output material
- Material& srcMat = materials[i];
- mat->AddProperty(&srcMat.diffuse, 1,AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR);
- mat->AddProperty(&srcMat.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
-
- // NOTE: Ignore transparency for the moment - it seems
- // unclear how to interpret the data
-#if 0
- if (!(minor > '0' && major == '3'))
- srcMat.transparency = 1.0f - srcMat.transparency;
- mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY);
-#endif
-
- // add shininess - Quick3D seems to use it ins its viewer
- srcMat.transparency = 16.f;
- mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS);
-
- int m = (int)aiShadingMode_Phong;
- mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL);
-
- if (srcMat.name.length)
- mat->AddProperty(&srcMat.name,AI_MATKEY_NAME);
-
- // Add a texture
- if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures)
- {
- srcMat.name.data[0] = '*';
- srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1],1000,
- (srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
- mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
-
- mesh->mNumFaces = (unsigned int)fidx[i].size();
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- // Now build the output mesh. First find out how many
- // vertices we'll need
- for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
- it != end; ++it)
- {
- mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
- (*it).second].indices.size();
- }
-
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiVector3D* norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- aiVector3D* uv;
- if (real < pScene->mNumTextures)
- {
- uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
- }
- else uv = NULL;
-
- // Build the final array
- unsigned int cnt = 0;
- for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
- it != end; ++it, ++faces)
- {
- Mesh& m = meshes[(*it).first];
- Face& face = m.faces[(*it).second];
- faces->mNumIndices = (unsigned int)face.indices.size();
- faces->mIndices = new unsigned int [faces->mNumIndices];
-
-
- aiVector3D faceNormal;
- bool fnOK = false;
-
- for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
- {
- if (face.indices[n] >= m.verts.size())
- {
- DefaultLogger::get()->warn("Quick3D: Vertex index overflow");
- face.indices[n] = 0;
- }
-
- // copy vertices
- *verts = m.verts[ face.indices[n] ];
-
- if (face.indices[n] >= m.normals.size() && faces->mNumIndices >= 3)
- {
- // we have no normal here - assign the face normal
- if (!fnOK)
- {
- const aiVector3D& pV1 = m.verts[ face.indices[0] ];
- const aiVector3D& pV2 = m.verts[ face.indices[1] ];
- const aiVector3D& pV3 = m.verts[ face.indices.size() - 1 ];
- faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize();
- fnOK = true;
- }
- *norms = faceNormal;
- }
- else *norms = m.normals[ face.indices[n] ];
-
- // copy texture coordinates
- if (uv && m.uv.size())
- {
- if (m.prevUVIdx != 0xffffffff && m.uv.size() >= m.verts.size()) // workaround
- {
- *uv = m.uv[face.indices[n]];
- }
- else
- {
- if (face.uvindices[n] >= m.uv.size())
- {
- DefaultLogger::get()->warn("Quick3D: Texture coordinate index overflow");
- face.uvindices[n] = 0;
- }
- *uv = m.uv[face.uvindices[n]];
- }
- uv->y = 1.f - uv->y;
- ++uv;
- }
-
- // setup the new vertex index
- faces->mIndices[n] = cnt;
- }
-
- }
- ++real;
- }
-
- // Delete our nice helper array
- delete[] fidx;
-
- // Now we need to attach the meshes to the root node of the scene
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int [pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- /*pScene->mRootNode->mTransformation *= aiMatrix4x4(
- 1.f, 0.f, 0.f, 0.f,
- 0.f, -1.f,0.f, 0.f,
- 0.f, 0.f, 1.f, 0.f,
- 0.f, 0.f, 0.f, 1.f);*/
-
- // Add cameras and light sources to the scene root node
- pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
- if (pScene->mRootNode->mNumChildren)
- {
- pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ];
-
- // the light source
- aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode();
- nd->mParent = pScene->mRootNode;
- nd->mName.Set("Q3DLight");
- nd->mTransformation = pScene->mRootNode->mTransformation;
- nd->mTransformation.Inverse();
-
- // camera
- nd = pScene->mRootNode->mChildren[1] = new aiNode();
- nd->mParent = pScene->mRootNode;
- nd->mName.Set("Q3DCamera");
- nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER
diff --git a/3rdparty/assimp/code/Q3DLoader.h b/3rdparty/assimp/code/Q3DLoader.h
deleted file mode 100644
index e26c034b..00000000
--- a/3rdparty/assimp/code/Q3DLoader.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Q3DLoader.h
- * @brief Declaration of the Q3D importer class.
- */
-#ifndef AI_Q3DLOADER_H_INCLUDED
-#define AI_Q3DLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the Quick3D Object and Scene formats.
-*/
-class Q3DImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- Q3DImporter();
-
- /** Destructor, private as well */
- ~Q3DImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- struct Material
- {
- Material()
- : diffuse (0.6f,0.6f,0.6f)
- , transparency (0.f)
- , texIdx (0xffffffff)
- {}
-
- aiString name;
- aiColor3D ambient, diffuse, specular;
- float transparency;
-
- unsigned int texIdx;
- };
-
- struct Face
- {
- Face(unsigned int s)
- : indices (s)
- , uvindices (s)
- , mat (0)
- {
- }
-
- std::vector<unsigned int> indices;
- std::vector<unsigned int> uvindices;
- unsigned int mat;
- };
-
- struct Mesh
- {
-
- std::vector<aiVector3D> verts;
- std::vector<aiVector3D> normals;
- std::vector<aiVector3D> uv;
- std::vector<Face> faces;
-
- uint32_t prevUVIdx;
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_Q3DIMPORTER_H_IN
diff --git a/3rdparty/assimp/code/RawLoader.cpp b/3rdparty/assimp/code/RawLoader.cpp
deleted file mode 100644
index c14ecdc1..00000000
--- a/3rdparty/assimp/code/RawLoader.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file RawLoader.cpp
- * @brief Implementation of the RAW importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-
-// internal headers
-#include "RawLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RAWImporter::RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RAWImporter::~RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"raw");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the list of all supported file extensions
-void RAWImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("raw");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void RAWImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // list of groups loaded from the file
- std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
- std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
-
- // now read all lines
- char line[4096];
- while (GetNextLine(buffer,line))
- {
- // if the line starts with a non-numeric identifier, it marks
- // the beginning of a new group
- const char* sz = line;SkipSpaces(&sz);
- if (IsLineEnd(*sz))continue;
- if (!IsNumeric(*sz))
- {
- const char* sz2 = sz;
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- const unsigned int length = (unsigned int)(sz2-sz);
-
- // find an existing group with this name
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
- {
- curGroup = it;sz2 = NULL;
- break;
- }
- }
- if (sz2)
- {
- outGroups.push_back(GroupInformation(std::string(sz,length)));
- curGroup = outGroups.end()-1;
- }
- }
- else
- {
- // there can be maximally 12 floats plus an extra texture file name
- float data[12];
- unsigned int num;
- for (num = 0; num < 12;++num)
- {
- if (!SkipSpaces(&sz) || !IsNumeric(*sz))break;
- sz = fast_atof_move(sz,data[num]);
- }
- if (num != 12 && num != 9)
- {
- DefaultLogger::get()->error("A line may have either 9 or 12 floats and an optional texture");
- continue;
- }
-
- MeshInformation* output = NULL;
-
- const char* sz2 = sz;
- unsigned int length;
- if (!IsLineEnd(*sz))
- {
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- length = (unsigned int)(sz2-sz);
- }
- else if (9 == num)
- {
- sz = "%default%";
- length = 9;
- }
- else
- {
- sz = "";
- length = 0;
- }
-
- // search in the list of meshes whether we have one with this texture
- for (std::vector< MeshInformation >::iterator it = (*curGroup).meshes.begin(),
- end = (*curGroup).meshes.end(); it != end; ++it)
- {
- if (length == (*it).name.length() && (length ? !::strcmp(sz,(*it).name.c_str()) : true))
- {
- output = &(*it);
- break;
- }
- }
- // if we don't have the mesh, create it
- if (!output)
- {
- (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
- output = &((*curGroup).meshes.back());
- }
- if (12 == num)
- {
- aiColor4D v(data[0],data[1],data[2],1.0f);
- output->colors.push_back(v);
- output->colors.push_back(v);
- output->colors.push_back(v);
-
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
- }
- else
- {
- output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- }
- }
- }
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<RawRoot>");
-
- // count the number of valid groups
- // (meshes can't be empty)
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if (!(*it).meshes.empty())
- {
- ++pScene->mRootNode->mNumChildren;
- pScene->mNumMeshes += (unsigned int)(*it).meshes.size();
- }
- }
-
- if (!pScene->mNumMeshes)
- {
- throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- aiNode** cc;
- if (1 == pScene->mRootNode->mNumChildren)
- {
- cc = &pScene->mRootNode;
- pScene->mRootNode->mNumChildren = 0;
- }
- else cc = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
-
- pScene->mNumMaterials = pScene->mNumMeshes;
- aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
-
- unsigned int meshIdx = 0;
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if ((*it).meshes.empty())continue;
-
- aiNode* node;
- if (pScene->mRootNode->mNumChildren)
- {
- node = *cc = new aiNode();
- node->mParent = pScene->mRootNode;
- }
- else node = *cc;++cc;
- node->mName.Set((*it).name);
-
- // add all meshes
- node->mNumMeshes = (unsigned int)(*it).meshes.size();
- unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
- for (std::vector< MeshInformation >::iterator it2 = (*it).meshes.begin(),
- end2 = (*it).meshes.end(); it2 != end2; ++it2)
- {
- ai_assert(!(*it2).vertices.empty());
-
- // allocate the mesh
- *pi++ = meshIdx;
- aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
- mesh->mMaterialIndex = meshIdx++;
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for the vertex components and copy them
- mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
- mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
- ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
-
- if ((*it2).colors.size())
- {
- ai_assert((*it2).colors.size() == mesh->mNumVertices);
-
- mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
- ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- // generate triangles
- ai_assert(0 == mesh->mNumVertices % 3);
- aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
- aiFace* const fcEnd = fc + mesh->mNumFaces;
- unsigned int n = 0;
- while (fc != fcEnd)
- {
- aiFace& f = *fc++;
- f.mIndices = new unsigned int[f.mNumIndices = 3];
- for (unsigned int m = 0; m < 3;++m)
- f.mIndices[m] = n++;
- }
-
- // generate a material for the mesh
- MaterialHelper* mat = new MaterialHelper();
-
- aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
- if ("%default%" == (*it2).name) // a gray default material
- {
- clr.r = clr.g = clr.b = 0.6f;
- }
- else if ((*it2).name.length() > 0) // a texture
- {
- aiString s;
- s.Set((*it2).name);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- *mats++ = mat;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
diff --git a/3rdparty/assimp/code/RawLoader.h b/3rdparty/assimp/code/RawLoader.h
deleted file mode 100644
index 6200adee..00000000
--- a/3rdparty/assimp/code/RawLoader.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file RAWLoader.h
- * @brief Declaration of the RAW importer class.
- */
-#ifndef AI_RAWLOADER_H_INCLUDED
-#define AI_RAWLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the PovRay RAW triangle format
-*/
-class RAWImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- RAWImporter();
-
- /** Destructor, private as well */
- ~RAWImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- struct MeshInformation
- {
- MeshInformation(const std::string& _name)
- : name(_name)
- {
- vertices.reserve(100);
- colors.reserve(100);
- }
-
- std::string name;
-
- std::vector<aiVector3D> vertices;
- std::vector<aiColor4D> colors;
- };
-
- struct GroupInformation
- {
- GroupInformation(const std::string& _name)
- : name(_name)
- {
- meshes.reserve(10);
- }
-
- std::string name;
- std::vector<MeshInformation> meshes;
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/3rdparty/assimp/code/RemoveComments.cpp b/3rdparty/assimp/code/RemoveComments.cpp
deleted file mode 100644
index a0a62af8..00000000
--- a/3rdparty/assimp/code/RemoveComments.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file RemoveComments.cpp
- * @brief Defines the CommentRemover utility class
- */
-
-#include "AssimpPCH.h"
-#include "RemoveComments.h"
-#include "ParsingUtils.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Remove line comments from a file
-void CommentRemover::RemoveLineComments(const char* szComment,
- char* szBuffer, char chReplacement /* = ' ' */)
-{
- // validate parameters
- ai_assert(NULL != szComment && NULL != szBuffer && *szComment);
-
- const size_t len = strlen(szComment);
- while (*szBuffer) {
-
- // skip over quotes
- if (*szBuffer == '\"' || *szBuffer == '\'')
- while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'') {};
-
- if (!strncmp(szBuffer,szComment,len)) {
- while (!IsLineEnd(*szBuffer))
- *szBuffer++ = chReplacement;
- }
- ++szBuffer;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Remove multi-line comments from a file
-void CommentRemover::RemoveMultiLineComments(const char* szCommentStart,
- const char* szCommentEnd,char* szBuffer,
- char chReplacement)
-{
- // validate parameters
- ai_assert(NULL != szCommentStart && NULL != szCommentEnd &&
- NULL != szBuffer && *szCommentStart && *szCommentEnd);
-
- const size_t len = strlen(szCommentEnd);
- const size_t len2 = strlen(szCommentStart);
-
- while (*szBuffer) {
- // skip over quotes
- if (*szBuffer == '\"' || *szBuffer == '\'')
- while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'') {};
-
- if (!strncmp(szBuffer,szCommentStart,len2)) {
- while (*szBuffer) {
- if (!::strncmp(szBuffer,szCommentEnd,len)) {
- for (unsigned int i = 0; i < len;++i)
- *szBuffer++ = chReplacement;
-
- break;
- }
- *szBuffer++ = chReplacement;
- }
- continue;
- }
- ++szBuffer;
- }
-}
-
-} // !! Assimp
diff --git a/3rdparty/assimp/code/RemoveComments.h b/3rdparty/assimp/code/RemoveComments.h
deleted file mode 100644
index 6c909955..00000000
--- a/3rdparty/assimp/code/RemoveComments.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Declares a helper class, "CommentRemover", which can be
- * used to remove comments (single and multi line) from a text file.
- */
-#ifndef AI_REMOVE_COMMENTS_H_INC
-#define AI_REMOVE_COMMENTS_H_INC
-
-#include "../include/aiAssert.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper class to remove single and multi line comments from a file
- *
- * Some mesh formats like MD5 have comments that are quite similar
- * to those in C or C++ so this code has been moved to a separate
- * module.
- */
-class ASSIMP_API CommentRemover
-{
- // class cannot be instanced
- CommentRemover() {}
-
-public:
-
- //! Remove single-line comments. The end of a line is
- //! expected to be either NL or CR or NLCR.
- //! \param szComment The start sequence of the comment, e.g. "//"
- //! \param szBuffer Buffer to work with
- //! \param chReplacement Character to be used as replacement
- //! for commented lines. By default this is ' '
- static void RemoveLineComments(const char* szComment,
- char* szBuffer, char chReplacement = ' ');
-
- //! Remove multi-line comments. The end of a line is
- //! expected to be either NL or CR or NLCR. Multi-line comments
- //! may not be nested (as in C).
- //! \param szCommentStart The start sequence of the comment, e.g. "/*"
- //! \param szCommentEnd The end sequence of the comment, e.g. "*/"
- //! \param szBuffer Buffer to work with
- //! \param chReplacement Character to be used as replacement
- //! for commented lines. By default this is ' '
- static void RemoveMultiLineComments(const char* szCommentStart,
- const char* szCommentEnd,char* szBuffer,
- char chReplacement = ' ');
-};
-} // ! Assimp
-
-#endif // !! AI_REMOVE_COMMENTS_H_INC
diff --git a/3rdparty/assimp/code/RemoveRedundantMaterials.cpp b/3rdparty/assimp/code/RemoveRedundantMaterials.cpp
deleted file mode 100644
index c2d4e9bb..00000000
--- a/3rdparty/assimp/code/RemoveRedundantMaterials.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file RemoveRedundantMaterials.cpp
- * @brief Implementation of the "RemoveRedundantMaterials" post processing step
-*/
-
-// internal headers
-#include "AssimpPCH.h"
-#include "RemoveRedundantMaterials.h"
-#include "ParsingUtils.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
-{
- // Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
- configFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("RemoveRedundantMatsProcess begin");
-
- unsigned int iCnt = 0, unreferenced = 0;
- if (pScene->mNumMaterials)
- {
- // Find out which materials are referenced by meshes
- std::vector<bool> abReferenced(pScene->mNumMaterials,false);
- for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
- abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
-
- // If a list of materials to be excluded was given, match the list with
- // our imported materials and 'salt' all positive matches to ensure that
- // we get unique hashes later.
- if (configFixedMaterials.length()) {
-
- std::list<std::string> strings;
- ConvertListToStrings(configFixedMaterials,strings);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- aiMaterial* mat = pScene->mMaterials[i];
-
- aiString name;
- mat->Get(AI_MATKEY_NAME,name);
-
- if (name.length) {
- std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
- if (it != strings.end()) {
-
- // Our brilliant 'salt': A single material property with ~ as first
- // character to mark it as internal and temporary.
- const int dummy = 1;
- ((MaterialHelper*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
-
- // Keep this material even if no mesh references it
- abReferenced[i] = true;
- DefaultLogger::get()->debug(std::string("Found positive match in exclusion list: \'") + name.data + "\'");
- }
- }
- }
- }
-
-
- // TODO: reimplement this algorithm to work in-place
-
- unsigned int* aiMappingTable = new unsigned int[pScene->mNumMaterials];
- unsigned int iNewNum = 0;
-
- // Iterate through all materials and calculate a hash for them
- // store all hashes in a list and so a quick search whether
- // we do already have a specific hash. This allows us to
- // determine which materials are identical.
- uint32_t* aiHashes;
- aiHashes = new uint32_t[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- // if the material is not referenced ... remove it
- if (!abReferenced[i]) {
- ++unreferenced;
- continue;
- }
-
- uint32_t me = aiHashes[i] = ((MaterialHelper*)pScene->mMaterials[i])->ComputeHash();
- for (unsigned int a = 0; a < i;++a)
- {
- if (me == aiHashes[a]) {
- ++iCnt;
- me = 0;
- aiMappingTable[i] = aiMappingTable[a];
- delete pScene->mMaterials[i];
- break;
- }
- }
- if (me) {
- aiMappingTable[i] = iNewNum++;
- }
- }
- if (iCnt) {
- // build an output material list
- aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
- ::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
- for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
- {
- // if the material is not referenced ... remove it
- if (!abReferenced[p])
- continue;
-
- // generate new names for all modified materials
- const unsigned int idx = aiMappingTable[p];
- if (ppcMaterials[idx])
- {
- aiString sz;
- sz.length = ::sprintf(sz.data,"JoinedMaterial_#%i",p);
- ((MaterialHelper*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
- }
- else ppcMaterials[idx] = pScene->mMaterials[p];
- }
- // update all material indices
- for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
- aiMesh* mesh = pScene->mMeshes[p];
- mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
- }
- // delete the old material list
- delete[] pScene->mMaterials;
- pScene->mMaterials = ppcMaterials;
- pScene->mNumMaterials = iNewNum;
- }
- // delete temporary storage
- delete[] aiHashes;
- delete[] aiMappingTable;
- }
- if (!iCnt)DefaultLogger::get()->debug("RemoveRedundantMatsProcess finished ");
- else
- {
- char szBuffer[128]; // should be sufficiently large
- ::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. %i redundant and %i unused materials",
- iCnt,unreferenced);
- DefaultLogger::get()->info(szBuffer);
- }
-}
diff --git a/3rdparty/assimp/code/RemoveRedundantMaterials.h b/3rdparty/assimp/code/RemoveRedundantMaterials.h
deleted file mode 100644
index 97297f5e..00000000
--- a/3rdparty/assimp/code/RemoveRedundantMaterials.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file RemoveRedundantMaterials.h
- * @brief Defines a post processing step to remove redundant materials
- */
-#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC
-#define AI_REMOVEREDUNDANTMATERIALS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class RemoveRedundantMatsTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** RemoveRedundantMatsProcess: Postprocessing steo to remove redundant
- * materials from the imported scene.
- */
-class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::RemoveRedundantMatsTest; // grant the unit test full access to us
-
-protected:
- /** Constructor to be privately used by Importer */
- RemoveRedundantMatsProcess();
-
- /** Destructor, private as well */
- ~RemoveRedundantMatsProcess();
-
-public:
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Set list of fixed (unmutable) materials
- * @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
- */
- void SetFixedMaterialsString(const std::string& fixed = "") {
- configFixedMaterials = fixed;
- }
-
- // -------------------------------------------------------------------
- /** @brief Get list of fixed (unmutable) materials
- * @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
- */
- const std::string& GetFixedMaterialsString() const {
- return configFixedMaterials;
- }
-
-private:
-
- //! Configuration option: list of all fixed materials
- std::string configFixedMaterials;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_REMOVEREDUNDANTMATERIALS_H_INC
diff --git a/3rdparty/assimp/code/RemoveVCProcess.cpp b/3rdparty/assimp/code/RemoveVCProcess.cpp
deleted file mode 100644
index 31ea56bb..00000000
--- a/3rdparty/assimp/code/RemoveVCProcess.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file Implementation of the post processing step to remove
- * any parts of the mesh structure from the imported data.
-*/
-
-#include "AssimpPCH.h"
-#include "RemoveVCProcess.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RemoveVCProcess::RemoveVCProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveVCProcess::~RemoveVCProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool RemoveVCProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_RemoveComponent) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Small helper function to delete all elements in a T** aray using delete
-template <typename T>
-inline void ArrayDelete(T**& in, unsigned int& num)
-{
- for (unsigned int i = 0; i < num; ++i)
- delete in[i];
-
- delete[] in;
- in = NULL;
- num = 0;
-}
-
-#if 0
-// ------------------------------------------------------------------------------------------------
-// Updates the node graph - removes all nodes which have the "remove" flag set and the
-// "don't remove" flag not set. Nodes with meshes are never deleted.
-bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
-{
- register bool b = false;
-
- std::list<aiNode*> mine;
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- {
- if (UpdateNodeGraph(node->mChildren[i],mine,false))
- b = true;
- }
-
- // somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
- // so we can do a simple comparison against MSB here
- if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
- {
- // this node needs to be removed
- if (node->mNumChildren)
- {
- childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
-
- // set all children to NULL to make sure they are not deleted when we delete ourself
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- node->mChildren[i] = NULL;
- }
- b = true;
- delete node;
- }
- else
- {
- AI_RC_UNMASK(node->mNumMeshes);
- childsOfParent.push_back(node);
-
- if (b)
- {
- // reallocate the array of our children here
- node->mNumChildren = (unsigned int)mine.size();
- aiNode** const children = new aiNode*[mine.size()];
- aiNode** ptr = children;
-
- for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
- it != end; ++it)
- {
- *ptr++ = *it;
- }
- delete[] node->mChildren;
- node->mChildren = children;
- return false;
- }
- }
- return b;
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void RemoveVCProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("RemoveVCProcess begin");
- bool bHas = false; //,bMasked = false;
-
- mScene = pScene;
-
- // handle animations
- if ( configDeleteFlags & aiComponent_ANIMATIONS)
- {
-
- bHas = true;
- ArrayDelete(pScene->mAnimations,pScene->mNumAnimations);
- }
-
- // handle textures
- if ( configDeleteFlags & aiComponent_TEXTURES)
- {
- bHas = true;
- ArrayDelete(pScene->mTextures,pScene->mNumTextures);
- }
-
- // handle materials
- if ( configDeleteFlags & aiComponent_MATERIALS && pScene->mNumMaterials)
- {
- bHas = true;
- for (unsigned int i = 1;i < pScene->mNumMaterials;++i)
- delete pScene->mMaterials[i];
-
- pScene->mNumMaterials = 1;
- MaterialHelper* helper = (MaterialHelper*) pScene->mMaterials[0];
- ai_assert(NULL != helper);
- helper->Clear();
-
- // gray
- aiColor3D clr(0.6f,0.6f,0.6f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // add a small ambient color value
- clr = aiColor3D(0.05f,0.05f,0.05f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString s;
- s.Set("Dummy_MaterialsRemoved");
- helper->AddProperty(&s,AI_MATKEY_NAME);
- }
-
- // handle light sources
- if ( configDeleteFlags & aiComponent_LIGHTS)
- {
- bHas = true;
- ArrayDelete(pScene->mLights,pScene->mNumLights);
- }
-
- // handle camneras
- if ( configDeleteFlags & aiComponent_CAMERAS)
- {
- bHas = true;
- ArrayDelete(pScene->mCameras,pScene->mNumCameras);
- }
-
- // handle meshes
- if (configDeleteFlags & aiComponent_MESHES)
- {
- bHas = true;
- ArrayDelete(pScene->mMeshes,pScene->mNumMeshes);
- }
- else
- {
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if ( ProcessMesh( pScene->mMeshes[a]))
- bHas = true;
- }
- }
-
-
- // now check whether the result is still a full scene
- if (!pScene->mNumMeshes || !pScene->mNumMaterials)
- {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- DefaultLogger::get()->debug("Setting AI_SCENE_FLAGS_INCOMPLETE flag");
-
- // If we have no meshes anymore we should also clear another flag ...
- if (!pScene->mNumMeshes)
- pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- }
-
- if (bHas)DefaultLogger::get()->info("RemoveVCProcess finished. Data structure cleanup has been done.");
- else DefaultLogger::get()->debug("RemoveVCProcess finished. Nothing to be done ...");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the step
-void RemoveVCProcess::SetupProperties(const Importer* pImp)
-{
- configDeleteFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,0x0);
- if (!configDeleteFlags)
- {
- DefaultLogger::get()->warn("RemoveVCProcess: AI_CONFIG_PP_RVC_FLAGS is zero.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
-{
- bool ret = false;
-
- // if all materials have been deleted let the material
- // index of the mesh point to the created default material
- if ( configDeleteFlags & aiComponent_MATERIALS)
- pMesh->mMaterialIndex = 0;
-
- // handle normals
- if (configDeleteFlags & aiComponent_NORMALS && pMesh->mNormals)
- {
- delete[] pMesh->mNormals;
- pMesh->mNormals = NULL;
- ret = true;
- }
-
- // handle tangents and bitangents
- if (configDeleteFlags & aiComponent_TANGENTS_AND_BITANGENTS && pMesh->mTangents)
- {
- delete[] pMesh->mTangents;
- pMesh->mTangents = NULL;
-
- delete[] pMesh->mBitangents;
- pMesh->mBitangents = NULL;
- ret = true;
- }
-
- // handle texture coordinates
- register bool b = (0 != (configDeleteFlags & aiComponent_TEXCOORDS));
- for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++real)
- {
- if (!pMesh->mTextureCoords[i])break;
- if (configDeleteFlags & aiComponent_TEXCOORDSn(real) || b)
- {
- delete pMesh->mTextureCoords[i];
- pMesh->mTextureCoords[i] = NULL;
- ret = true;
-
- if (!b)
- {
- // collapse the rest of the array
- for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
- pMesh->mTextureCoords[a-1] = pMesh->mTextureCoords[a];
-
- pMesh->mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS-1] = NULL;
- continue;
- }
- }
- ++i;
- }
-
- // handle vertex colors
- b = (0 != (configDeleteFlags & aiComponent_COLORS));
- for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_COLOR_SETS; ++real)
- {
- if (!pMesh->mColors[i])break;
- if (configDeleteFlags & aiComponent_COLORSn(i) || b)
- {
- delete pMesh->mColors[i];
- pMesh->mColors[i] = NULL;
- ret = true;
-
- if (!b)
- {
- // collapse the rest of the array
- for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
- pMesh->mColors[a-1] = pMesh->mColors[a];
-
- pMesh->mColors[AI_MAX_NUMBER_OF_COLOR_SETS-1] = NULL;
- continue;
- }
- }
- ++i;
- }
-
- // handle bones
- if (configDeleteFlags & aiComponent_BONEWEIGHTS && pMesh->mBones)
- {
- ArrayDelete(pMesh->mBones,pMesh->mNumBones);
- ret = true;
- }
- return ret;
-}
diff --git a/3rdparty/assimp/code/RemoveVCProcess.h b/3rdparty/assimp/code/RemoveVCProcess.h
deleted file mode 100644
index bd315656..00000000
--- a/3rdparty/assimp/code/RemoveVCProcess.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to remove specific parts of the scene */
-#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
-#define AI_REMOVEVCPROCESS_H_INCLUDED
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class RemoveVCProcessTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** RemoveVCProcess: Class to exclude specific parts of the data structure
- * from further processing by removing them,
-*/
-class ASSIMP_API RemoveVCProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::RemoveVCProcessTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- RemoveVCProcess();
-
- /** Destructor, private as well */
- ~RemoveVCProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Manually setup the configuration flags for the step
- *
- * @param Bitwise combintion of the #aiComponent enumerated values.
- */
- void SetDeleteFlags(unsigned int f)
- {
- configDeleteFlags = f;
- }
-
- // -------------------------------------------------------------------
- /** Query the current configuration.
- */
- unsigned int GetDeleteFlags() const
- {
- return configDeleteFlags;
- }
-
-private:
-
- bool ProcessMesh (aiMesh* pcMesh);
-
- /** Configuration flag
- */
- unsigned int configDeleteFlags;
-
- /** The scene we're working with
- */
- aiScene* mScene;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_REMOVEVCPROCESS_H_INCLUDED
diff --git a/3rdparty/assimp/code/SGSpatialSort.cpp b/3rdparty/assimp/code/SGSpatialSort.cpp
deleted file mode 100644
index 705dafc9..00000000
--- a/3rdparty/assimp/code/SGSpatialSort.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the helper class to quickly find
-vertices close to a given position. Special implementation for
-the 3ds loader handling smooth groups correctly */
-
-#include "AssimpPCH.h"
-#include "SGSpatialSort.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-SGSpatialSort::SGSpatialSort()
-{
- // define the reference plane. We choose some arbitrary vector away from all basic axises
- // in the hope that no model spreads all its vertices along this plane.
- mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f);
- mPlaneNormal.Normalize();
-}
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SGSpatialSort::~SGSpatialSort()
-{
- // nothing to do here, everything destructs automatically
-}
-// ------------------------------------------------------------------------------------------------
-void SGSpatialSort::Add(const aiVector3D& vPosition, unsigned int index,
- unsigned int smoothingGroup)
-{
- // store position by index and distance
- float distance = vPosition * mPlaneNormal;
- mPositions.push_back( Entry( index, vPosition,
- distance, smoothingGroup));
-}
-// ------------------------------------------------------------------------------------------------
-void SGSpatialSort::Prepare()
-{
- // now sort the array ascending by distance.
- std::sort( this->mPositions.begin(), this->mPositions.end());
-}
-// ------------------------------------------------------------------------------------------------
-// Returns an iterator for all positions close to the given position.
-void SGSpatialSort::FindPositions( const aiVector3D& pPosition,
- uint32_t pSG,
- float pRadius,
- std::vector<unsigned int>& poResults,
- bool exactMatch /*= false*/) const
-{
- float dist = pPosition * mPlaneNormal;
- float minDist = dist - pRadius, maxDist = dist + pRadius;
-
- // clear the array in this strange fashion because a simple clear() would also deallocate
- // the array which we want to avoid
- poResults.erase( poResults.begin(), poResults.end());
-
- // quick check for positions outside the range
- if ( mPositions.size() == 0)
- return;
- if ( maxDist < mPositions.front().mDistance)
- return;
- if ( minDist > mPositions.back().mDistance)
- return;
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while ( binaryStepSize > 1)
- {
- if ( mPositions[index].mDistance < minDist)
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while ( index > 0 && mPositions[index].mDistance > minDist)
- index--;
- while ( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
- index++;
-
- // Mow start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the given radius to the result aray
-
- float squareEpsilon = pRadius * pRadius;
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- std::vector<Entry>::const_iterator end = mPositions.end();
-
- if (exactMatch)
- {
- while ( it->mDistance < maxDist)
- {
- if ((it->mPosition - pPosition).SquareLength() < squareEpsilon && it->mSmoothGroups == pSG)
- {
- poResults.push_back( it->mIndex);
- }
- ++it;
- if ( end == it )break;
- }
- }
- else
- {
- // if the given smoothing group is 0, we'll return all surrounding vertices
- if (!pSG)
- {
- while ( it->mDistance < maxDist)
- {
- if ((it->mPosition - pPosition).SquareLength() < squareEpsilon)
- poResults.push_back( it->mIndex);
- ++it;
- if ( end == it)break;
- }
- }
- else while ( it->mDistance < maxDist)
- {
- if ((it->mPosition - pPosition).SquareLength() < squareEpsilon &&
- (it->mSmoothGroups & pSG || !it->mSmoothGroups))
- {
- poResults.push_back( it->mIndex);
- }
- ++it;
- if ( end == it)break;
- }
- }
-}
-
-
diff --git a/3rdparty/assimp/code/SGSpatialSort.h b/3rdparty/assimp/code/SGSpatialSort.h
deleted file mode 100644
index 4c597bc1..00000000
--- a/3rdparty/assimp/code/SGSpatialSort.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** Small helper classes to optimise finding vertizes close to a given location
- */
-#ifndef AI_D3DSSPATIALSORT_H_INC
-#define AI_D3DSSPATIALSORT_H_INC
-
-#include <vector>
-#include "../include/aiTypes.h"
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** Specialized version of SpatialSort to support smoothing groups
- * This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their
- * normal computation code in SmoothingGroups.inl, the LWO loader has its own
- * implementation to handle all details of its file format correctly.
- */
-// ----------------------------------------------------------------------------------
-class SGSpatialSort
-{
-public:
-
- SGSpatialSort();
-
- // -------------------------------------------------------------------
- /** Construction from a given face array, handling smoothing groups
- * properly
- */
- SGSpatialSort(const std::vector<aiVector3D>& vPositions);
-
- // -------------------------------------------------------------------
- /** Add a vertex to the spatial sort
- * @param vPosition Vertex position to be added
- * @param index Index of the vrtex
- * @param smoothingGroup SmoothingGroup for this vertex
- */
- void Add(const aiVector3D& vPosition, unsigned int index,
- unsigned int smoothingGroup);
-
- // -------------------------------------------------------------------
- /** Prepare the spatial sorter for use. This step runs in O(logn)
- */
- void Prepare();
-
- /** Destructor */
- ~SGSpatialSort();
-
- // -------------------------------------------------------------------
- /** Returns an iterator for all positions close to the given position.
- * @param pPosition The position to look for vertices.
- * @param pSG Only included vertices with at least one shared smooth group
- * @param pRadius Maximal distance from the position a vertex may have
- * to be counted in.
- * @param poResults The container to store the indices of the found
- * positions. Will be emptied by the call so it may contain anything.
- * @param exactMatch Specifies whether smoothing groups are bit masks
- * (false) or integral values (true). In the latter case, a vertex
- * cannot belong to more than one smoothing group.
- * @return An iterator to iterate over all vertices in the given area.
- */
- // -------------------------------------------------------------------
- void FindPositions( const aiVector3D& pPosition, uint32_t pSG,
- float pRadius, std::vector<unsigned int>& poResults,
- bool exactMatch = false) const;
-
-protected:
- /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
- aiVector3D mPlaneNormal;
-
- // -------------------------------------------------------------------
- /** An entry in a spatially sorted position array. Consists of a
- * vertex index, its position and its precalculated distance from
- * the reference plane */
- // -------------------------------------------------------------------
- struct Entry
- {
- unsigned int mIndex; ///< The vertex referred by this entry
- aiVector3D mPosition; ///< Position
- uint32_t mSmoothGroups;
- float mDistance; ///< Distance of this vertex to the sorting plane
-
- Entry() { /** intentionally not initialized.*/ }
- Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG)
- :
- mIndex( pIndex),
- mPosition( pPosition),
- mSmoothGroups (pSG),
- mDistance( pDistance)
- { }
-
- bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
- };
-
- // all positions, sorted by distance to the sorting plane
- std::vector<Entry> mPositions;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SPATIALSORT_H_INC
diff --git a/3rdparty/assimp/code/SMDLoader.cpp b/3rdparty/assimp/code/SMDLoader.cpp
deleted file mode 100644
index e3646458..00000000
--- a/3rdparty/assimp/code/SMDLoader.cpp
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file SMDLoader.cpp
- * @brief Implementation of the SMD importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-
-// internal headers
-#include "SMDLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-SMDImporter::SMDImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SMDImporter::~SMDImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool SMDImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool) const
-{
- // fixme: auto format detection
- return SimpleExtensionCheck(pFile,"smd","vta");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported file extensions
-void SMDImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("smd");
- extensions.insert("vta");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void SMDImporter::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_SMD_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_SMD_KEYFRAME,0xffffffff);
- if (0xffffffff == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void SMDImporter::InternReadFile(
- const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open SMD/VTA file " + pFile + ".");
- }
-
- iFileSize = (unsigned int)file->FileSize();
-
- // Allocate storage and copy the contents of the file to a memory buffer
- this->pScene = pScene;
-
- std::vector<char> buff(iFileSize+1);
- TextFileToBuffer(file.get(),buff);
- mBuffer = &buff[0];
-
- iSmallestFrame = (1 << 31);
- bHasUVs = true;
- iLineNumber = 1;
-
- // Reserve enough space for ... hm ... 10 textures
- aszTextures.reserve(10);
-
- // Reserve enough space for ... hm ... 1000 triangles
- asTriangles.reserve(1000);
-
- // Reserve enough space for ... hm ... 20 bones
- asBones.reserve(20);
-
-
- // parse the file ...
- ParseFile();
-
- // If there are no triangles it seems to be an animation SMD,
- // containing only the animation skeleton.
- if (asTriangles.empty())
- {
- if (asBones.empty())
- {
- throw DeadlyImportError("SMD: No triangles and no bones have "
- "been found in the file. This file seems to be invalid.");
- }
-
- // Set the flag in the scene structure which indicates
- // that there is nothing than an animation skeleton
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- if (!asBones.empty())
- {
- // Check whether all bones have been initialized
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if (!(*i).mName.length())
- {
- DefaultLogger::get()->warn("SMD: Not all bones have been initialized");
- break;
- }
- }
-
- // now fix invalid time values and make sure the animation starts at frame 0
- FixTimeValues();
-
- // compute absolute bone transformation matrices
- // ComputeAbsoluteBoneTransformations();
- }
-
- if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
- {
- // create output meshes
- CreateOutputMeshes();
-
- // build an output material list
- CreateOutputMaterials();
- }
-
- // build the output animation
- CreateOutputAnimations();
-
- // build output nodes (bones are added as empty dummy nodes)
- CreateOutputNodes();
-
- if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
- {
- SkeletonMeshBuilder skeleton(pScene);
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Write an error message with line number to the log file
-void SMDImporter::LogErrorNoThrow(const char* msg)
-{
- char szTemp[1024];
- sprintf(szTemp,"Line %i: %s",iLineNumber,msg);
- DefaultLogger::get()->error(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Write a warning with line number to the log file
-void SMDImporter::LogWarning(const char* msg)
-{
- char szTemp[1024];
- ai_assert(strlen(msg) < 1000);
- DefaultLogger::get()->warn(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Fix invalid time values in the file
-void SMDImporter::FixTimeValues()
-{
- double dDelta = (double)iSmallestFrame;
- double dMax = 0.0f;
- for (std::vector<SMD::Bone>::iterator
- iBone = asBones.begin();
- iBone != asBones.end();++iBone)
- {
- for (std::vector<SMD::Bone::Animation::MatrixKey>::iterator
- iKey = (*iBone).sAnim.asKeys.begin();
- iKey != (*iBone).sAnim.asKeys.end();++iKey)
- {
- (*iKey).dTime -= dDelta;
- dMax = std::max(dMax, (*iKey).dTime);
- }
- }
- dLengthOfAnim = dMax;
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output meshes
-void SMDImporter::CreateOutputMeshes()
-{
- if (aszTextures.empty())
- aszTextures.push_back(std::string());
-
- // we need to sort all faces by their material index
- // in opposition to other loaders we can be sure that each
- // material is at least used once.
- pScene->mNumMeshes = (unsigned int) aszTextures.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- typedef std::vector<unsigned int> FaceList;
- FaceList* aaiFaces = new FaceList[pScene->mNumMeshes];
-
- // approximate the space that will be required
- unsigned int iNum = (unsigned int)asTriangles.size() / pScene->mNumMeshes;
- iNum += iNum >> 1;
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- aaiFaces[i].reserve(iNum);
-
-
- // collect all faces
- iNum = 0;
- for (std::vector<SMD::Face>::const_iterator
- iFace = asTriangles.begin();
- iFace != asTriangles.end();++iFace,++iNum)
- {
- if (0xffffffff == (*iFace).iTexture)aaiFaces[(*iFace).iTexture].push_back( 0 );
- else if ((*iFace).iTexture >= aszTextures.size())
- {
- DefaultLogger::get()->error("[SMD/VTA] Material index overflow in face");
- aaiFaces[(*iFace).iTexture].push_back((unsigned int)aszTextures.size()-1);
- }
- else aaiFaces[(*iFace).iTexture].push_back(iNum);
- }
-
- // now create the output meshes
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiMesh*& pcMesh = pScene->mMeshes[i] = new aiMesh();
- ai_assert(!aaiFaces[i].empty()); // should not be empty ...
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mNumVertices = (unsigned int)aaiFaces[i].size()*3;
- pcMesh->mNumFaces = (unsigned int)aaiFaces[i].size();
- pcMesh->mMaterialIndex = i;
-
- // storage for bones
- typedef std::pair<unsigned int,float> TempWeightListEntry;
- typedef std::vector< TempWeightListEntry > TempBoneWeightList;
-
- TempBoneWeightList* aaiBones = new TempBoneWeightList[asBones.size()]();
-
- // try to reserve enough memory without wasting too much
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- aaiBones[iBone].reserve(pcMesh->mNumVertices/asBones.size());
- }
-
- // allocate storage
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
- aiVector3D* pcNormals = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcVerts = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
-
- aiVector3D* pcUVs = NULL;
- if (bHasUVs)
- {
- pcUVs = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
- }
-
- iNum = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)
- {
- pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
- pcMesh->mFaces[iFace].mNumIndices = 3;
-
- // fill the vertices
- unsigned int iSrcFace = aaiFaces[i][iFace];
- SMD::Face& face = asTriangles[iSrcFace];
-
- *pcVerts++ = face.avVertices[0].pos;
- *pcVerts++ = face.avVertices[1].pos;
- *pcVerts++ = face.avVertices[2].pos;
-
- // fill the normals
- *pcNormals++ = face.avVertices[0].nor;
- *pcNormals++ = face.avVertices[1].nor;
- *pcNormals++ = face.avVertices[2].nor;
-
- // fill the texture coordinates
- if (pcUVs)
- {
- *pcUVs++ = face.avVertices[0].uv;
- *pcUVs++ = face.avVertices[1].uv;
- *pcUVs++ = face.avVertices[2].uv;
- }
-
- for (unsigned int iVert = 0; iVert < 3;++iVert)
- {
- float fSum = 0.0f;
- for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
- {
- TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
-
- // FIX: The second check is here just to make sure we won't
- // assign more than one weight to a single vertex index
- if (pairval.first >= asBones.size() ||
- pairval.first == face.avVertices[iVert].iParentNode)
- {
- DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
- "The bone index will be ignored, the weight will be assigned "
- "to the vertex' parent node");
- continue;
- }
- aaiBones[pairval.first].push_back(TempWeightListEntry(iNum,pairval.second));
- fSum += pairval.second;
- }
- // ******************************************************************
- // If the sum of all vertex weights is not 1.0 we must assign
- // the rest to the vertex' parent node. Well, at least the doc says
- // we should ...
- // FIX: We use 0.975 as limit, floating-point inaccuracies seem to
- // be very strong in some SMD exporters. Furthermore it is possible
- // that the parent of a vertex is 0xffffffff (if the corresponding
- // entry in the file was unreadable)
- // ******************************************************************
- if (fSum < 0.975f && face.avVertices[iVert].iParentNode != 0xffffffff)
- {
- if (face.avVertices[iVert].iParentNode >= asBones.size())
- {
- DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
- "The index of the vertex parent bone is invalid. "
- "The remaining weights will be normalized to 1.0");
-
- if (fSum)
- {
- fSum = 1 / fSum;
- for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
- {
- TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
- if (pairval.first >= asBones.size())continue;
- aaiBones[pairval.first].back().second *= fSum;
- }
- }
- }
- else
- {
- aaiBones[face.avVertices[iVert].iParentNode].push_back(
- TempWeightListEntry(iNum,1.0f-fSum));
- }
- }
- pcMesh->mFaces[iFace].mIndices[iVert] = iNum++;
- }
- }
-
- // now build all bones of the mesh
- iNum = 0;
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- if (!aaiBones[iBone].empty())++iNum;
-
- if (false && iNum)
- {
- pcMesh->mNumBones = iNum;
- pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
- iNum = 0;
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- if (aaiBones[iBone].empty())continue;
- aiBone*& bone = pcMesh->mBones[iNum] = new aiBone();
-
- bone->mNumWeights = (unsigned int)aaiBones[iBone].size();
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- bone->mOffsetMatrix = asBones[iBone].mOffsetMatrix;
- bone->mName.Set( asBones[iBone].mName );
-
- asBones[iBone].bIsUsed = true;
-
- for (unsigned int iWeight = 0; iWeight < bone->mNumWeights;++iWeight)
- {
- bone->mWeights[iWeight].mVertexId = aaiBones[iBone][iWeight].first;
- bone->mWeights[iWeight].mWeight = aaiBones[iBone][iWeight].second;
- }
- ++iNum;
- }
- }
- delete[] aaiBones;
- }
- delete[] aaiFaces;
-}
-
-// ------------------------------------------------------------------------------------------------
-// add bone child nodes
-void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
-{
- ai_assert(NULL != pcNode && 0 == pcNode->mNumChildren && NULL == pcNode->mChildren);
-
- // first count ...
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
- if (bone.iParent == iParent)++pcNode->mNumChildren;
- }
-
- // now allocate the output array
- pcNode->mChildren = new aiNode*[pcNode->mNumChildren];
-
- // and fill all subnodes
- unsigned int qq = 0;
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
- if (bone.iParent != iParent)continue;
-
- aiNode* pc = pcNode->mChildren[qq++] = new aiNode();
- pc->mName.Set(bone.mName);
-
- // store the local transformation matrix of the bind pose
- pc->mTransformation = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrix;
- pc->mParent = pcNode;
-
- // add children to this node, too
- AddBoneChildren(pc,i);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output nodes
-void SMDImporter::CreateOutputNodes()
-{
- pScene->mRootNode = new aiNode();
- if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
- {
- // create one root node that renders all meshes
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
- }
-
- // now add all bones as dummy sub nodes to the graph
- // AddBoneChildren(pScene->mRootNode,(uint32_t)-1);
-
- // if we have only one bone we can even remove the root node
- if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE &&
- 1 == pScene->mRootNode->mNumChildren)
- {
- aiNode* pcOldRoot = pScene->mRootNode;
- pScene->mRootNode = pcOldRoot->mChildren[0];
- pcOldRoot->mChildren[0] = NULL;
- delete pcOldRoot;
-
- pScene->mRootNode->mParent = NULL;
- }
- else
- {
- ::strcpy(pScene->mRootNode->mName.data, "<SMD_root>");
- pScene->mRootNode->mName.length = 10;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output animations
-void SMDImporter::CreateOutputAnimations()
-{
- unsigned int iNumBones = 0;
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if ((*i).bIsUsed)++iNumBones;
- }
- if (!iNumBones)
- {
- // just make sure this case doesn't occur ... (it could occur
- // if the file was invalid)
- return;
- }
-
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- aiAnimation*& anim = pScene->mAnimations[0] = new aiAnimation();
-
- anim->mDuration = dLengthOfAnim;
- anim->mNumChannels = iNumBones;
- anim->mTicksPerSecond = 25.0; // FIXME: is this correct?
-
- aiNodeAnim** pp = anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
-
- // now build valid keys
- unsigned int a = 0;
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if (!(*i).bIsUsed)continue;
-
- aiNodeAnim* p = pp[a] = new aiNodeAnim();
-
- // copy the name of the bone
- p->mNodeName.Set( i->mName);
-
- p->mNumRotationKeys = (unsigned int) (*i).sAnim.asKeys.size();
- if (p->mNumRotationKeys)
- {
- p->mNumPositionKeys = p->mNumRotationKeys;
- aiVectorKey* pVecKeys = p->mPositionKeys = new aiVectorKey[p->mNumRotationKeys];
- aiQuatKey* pRotKeys = p->mRotationKeys = new aiQuatKey[p->mNumRotationKeys];
-
- for (std::vector<SMD::Bone::Animation::MatrixKey>::const_iterator
- qq = (*i).sAnim.asKeys.begin();
- qq != (*i).sAnim.asKeys.end(); ++qq)
- {
- pRotKeys->mTime = pVecKeys->mTime = (*qq).dTime;
-
- // compute the rotation quaternion from the euler angles
- pRotKeys->mValue = aiQuaternion( (*qq).vRot.x, (*qq).vRot.y, (*qq).vRot.z );
- pVecKeys->mValue = (*qq).vPos;
-
- ++pVecKeys; ++pRotKeys;
- }
- }
- ++a;
-
- // there are no scaling keys ...
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SMDImporter::ComputeAbsoluteBoneTransformations()
-{
- // For each bone: determine the key with the lowest time value
- // theoretically the SMD format should have all keyframes
- // in order. However, I've seen a file where this wasn't true.
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
-
- uint32_t iIndex = 0;
- double dMin = 10e10;
- for (unsigned int i = 0; i < bone.sAnim.asKeys.size();++i)
- {
- double d = std::min(bone.sAnim.asKeys[i].dTime,dMin);
- if (d < dMin)
- {
- dMin = d;
- iIndex = i;
- }
- }
- bone.sAnim.iFirstTimeKey = iIndex;
- }
-
- unsigned int iParent = 0;
- while (iParent < asBones.size())
- {
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- SMD::Bone& bone = asBones[iBone];
-
- if (iParent == bone.iParent)
- {
- SMD::Bone& parentBone = asBones[iParent];
-
-
- uint32_t iIndex = bone.sAnim.iFirstTimeKey;
- const aiMatrix4x4& mat = bone.sAnim.asKeys[iIndex].matrix;
- aiMatrix4x4& matOut = bone.sAnim.asKeys[iIndex].matrixAbsolute;
-
- // The same for the parent bone ...
- iIndex = parentBone.sAnim.iFirstTimeKey;
- const aiMatrix4x4& mat2 = parentBone.sAnim.asKeys[iIndex].matrixAbsolute;
-
- // Compute the absolute transformation matrix
- matOut = mat * mat2;
- }
- }
- ++iParent;
- }
-
- // Store the inverse of the absolute transformation matrix
- // of the first key as bone offset matrix
- for (iParent = 0; iParent < asBones.size();++iParent)
- {
- SMD::Bone& bone = asBones[iParent];
- bone.mOffsetMatrix = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrixAbsolute;
- bone.mOffsetMatrix.Inverse();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output materials
-void SMDImporter::CreateOutputMaterials()
-{
- pScene->mNumMaterials = (unsigned int)aszTextures.size();
- pScene->mMaterials = new aiMaterial*[std::max(1u, pScene->mNumMaterials)];
-
- for (unsigned int iMat = 0; iMat < pScene->mNumMaterials;++iMat)
- {
- MaterialHelper* pcMat = new MaterialHelper();
- pScene->mMaterials[iMat] = pcMat;
-
- aiString szName;
- szName.length = (size_t)::sprintf(szName.data,"Texture_%i",iMat);
- pcMat->AddProperty(&szName,AI_MATKEY_NAME);
-
- if (aszTextures[iMat].length())
- {
- ::strcpy(szName.data, aszTextures[iMat].c_str() );
- szName.length = aszTextures[iMat].length();
- pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-
- // create a default material if necessary
- if (0 == pScene->mNumMaterials)
- {
- pScene->mNumMaterials = 1;
-
- MaterialHelper* pcHelper = new MaterialHelper();
- pScene->mMaterials[0] = pcHelper;
-
- int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.7f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the file
-void SMDImporter::ParseFile()
-{
- const char* szCurrent = mBuffer;
-
- // read line per line ...
- while (true)
- {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "version <n> \n", <n> should be 1 for hl and hl SMD files
- if (TokenMatch(szCurrent,"version",7))
- {
- if (!SkipSpaces(szCurrent,&szCurrent)) break;
- if (1 != strtol10(szCurrent,&szCurrent))
- {
- DefaultLogger::get()->warn("SMD.version is not 1. This "
- "file format is not known. Continuing happily ...");
- }
- continue;
- }
- // "nodes\n" - Starts the node section
- if (TokenMatch(szCurrent,"nodes",5))
- {
- ParseNodesSection(szCurrent,&szCurrent);
- continue;
- }
- // "triangles\n" - Starts the triangle section
- if (TokenMatch(szCurrent,"triangles",9))
- {
- ParseTrianglesSection(szCurrent,&szCurrent);
- continue;
- }
- // "vertexanimation\n" - Starts the vertex animation section
- if (TokenMatch(szCurrent,"vertexanimation",15))
- {
- bHasUVs = false;
- ParseVASection(szCurrent,&szCurrent);
- continue;
- }
- // "skeleton\n" - Starts the skeleton section
- if (TokenMatch(szCurrent,"skeleton",8))
- {
- ParseSkeletonSection(szCurrent,&szCurrent);
- continue;
- }
- SkipLine(szCurrent,&szCurrent);
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int SMDImporter::GetTextureIndex(const std::string& filename)
-{
- unsigned int iIndex = 0;
- for (std::vector<std::string>::const_iterator
- i = aszTextures.begin();
- i != aszTextures.end();++i,++iIndex)
- {
- // case-insensitive ... it's a path
- if (0 == ASSIMP_stricmp ( filename.c_str(),(*i).c_str()))return iIndex;
- }
- iIndex = (unsigned int)aszTextures.size();
- aszTextures.push_back(filename);
- return iIndex;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the nodes section of the file
-void SMDImporter::ParseNodesSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- while (true)
- {
- // "end\n" - Ends the nodes section
- if (0 == ASSIMP_strincmp(szCurrent,"end",3) &&
- IsSpaceOrNewLine(*(szCurrent+3)))
- {
- szCurrent += 4;
- break;
- }
- ParseNodeInfo(szCurrent,&szCurrent);
- }
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the triangles section of the file
-void SMDImporter::ParseTrianglesSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- // Parse a triangle, parse another triangle, parse the next triangle ...
- // and so on until we reach a token that looks quite similar to "end"
- while (true)
- {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the triangles section
- if (TokenMatch(szCurrent,"end",3))
- break;
- ParseTriangle(szCurrent,&szCurrent);
- }
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-// ------------------------------------------------------------------------------------------------
-// Parse the vertex animation section of the file
-void SMDImporter::ParseVASection(const char* szCurrent,
- const char** szCurrentOut)
-{
- unsigned int iCurIndex = 0;
- while (true)
- {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the "vertexanimation" section
- if (TokenMatch(szCurrent,"end",3))
- break;
-
- // "time <n>\n"
- if (TokenMatch(szCurrent,"time",4))
- {
- // NOTE: The doc says that time values COULD be negative ...
- // NOTE2: this is the shape key -> valve docs
- int iTime = 0;
- if (!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime)break;
- SkipLine(szCurrent,&szCurrent);
- }
- else
- {
- if (0 == iCurIndex)
- {
- asTriangles.push_back(SMD::Face());
- }
- if (++iCurIndex == 3)iCurIndex = 0;
- ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
- }
- }
-
- if (iCurIndex != 2 && !asTriangles.empty())
- {
- // we want to no degenerates, so throw this triangle away
- asTriangles.pop_back();
- }
-
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-// ------------------------------------------------------------------------------------------------
-// Parse the skeleton section of the file
-void SMDImporter::ParseSkeletonSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- int iTime = 0;
- while (true)
- {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the skeleton section
- if (TokenMatch(szCurrent,"end",3))
- break;
-
- // "time <n>\n" - Specifies the current animation frame
- else if (TokenMatch(szCurrent,"time",4))
- {
- // NOTE: The doc says that time values COULD be negative ...
- if (!ParseSignedInt(szCurrent,&szCurrent,iTime))break;
-
- iSmallestFrame = std::min(iSmallestFrame,iTime);
- SkipLine(szCurrent,&szCurrent);
- }
- else ParseSkeletonElement(szCurrent,&szCurrent,iTime);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-#define SMDI_PARSE_RETURN { \
- SkipLine(szCurrent,&szCurrent); \
- *szCurrentOut = szCurrent; \
- return; \
-}
-// ------------------------------------------------------------------------------------------------
-// Parse a node line
-void SMDImporter::ParseNodeInfo(const char* szCurrent,
- const char** szCurrentOut)
-{
- unsigned int iBone = 0;
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- if (!ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone index");
- SMDI_PARSE_RETURN;
- }
- // add our bone to the list
- if (iBone >= asBones.size())asBones.resize(iBone+1);
- SMD::Bone& bone = asBones[iBone];
-
- bool bQuota = true;
- if ('\"' != *szCurrent)
- {
- LogWarning("Bone name is expcted to be enclosed in "
- "double quotation marks. ");
- bQuota = false;
- }
- else ++szCurrent;
-
- const char* szEnd = szCurrent;
- while (true)
- {
- if (bQuota && '\"' == *szEnd)
- {
- iBone = (unsigned int)(szEnd - szCurrent);
- ++szEnd;
- break;
- }
- else if (IsSpaceOrNewLine(*szEnd))
- {
- iBone = (unsigned int)(szEnd - szCurrent);
- break;
- }
- else if (!(*szEnd))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone name");
- SMDI_PARSE_RETURN;
- }
- ++szEnd;
- }
- bone.mName = std::string(szCurrent,iBone);
- szCurrent = szEnd;
-
- // the only negative bone parent index that could occur is -1 AFAIK
- if (!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
- SMDI_PARSE_RETURN;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a skeleton element
-void SMDImporter::ParseSkeletonElement(const char* szCurrent,
- const char** szCurrentOut,int iTime)
-{
- aiVector3D vPos;
- aiVector3D vRot;
-
- unsigned int iBone = 0;
- if (!ParseUnsignedInt(szCurrent,&szCurrent,iBone))
- {
- DefaultLogger::get()->error("Unexpected EOF/EOL while parsing bone index");
- SMDI_PARSE_RETURN;
- }
- if (iBone >= asBones.size())
- {
- LogErrorNoThrow("Bone index in skeleton section is out of range");
- SMDI_PARSE_RETURN;
- }
- SMD::Bone& bone = asBones[iBone];
-
- bone.sAnim.asKeys.push_back(SMD::Bone::Animation::MatrixKey());
- SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
-
- key.dTime = (double)iTime;
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
- SMDI_PARSE_RETURN;
- }
- // build the transformation matrix of the key
- key.matrix.FromEulerAnglesXYZ(vRot.x,vRot.y,vRot.z);
- {
- aiMatrix4x4 mTemp;
- mTemp.a4 = vPos.x;
- mTemp.b4 = vPos.y;
- mTemp.c4 = vPos.z;
- key.matrix = key.matrix * mTemp;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a triangle
-void SMDImporter::ParseTriangle(const char* szCurrent,
- const char** szCurrentOut)
-{
- asTriangles.push_back(SMD::Face());
- SMD::Face& face = asTriangles.back();
-
- if (!SkipSpaces(szCurrent,&szCurrent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
- return;
- }
-
- // read the texture file name
- const char* szLast = szCurrent;
- while (!IsSpaceOrNewLine(*szCurrent++)) {};
-
- // ... and get the index that belongs to this file name
- face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
-
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
-
- // load three vertices
- for (unsigned int iVert = 0; iVert < 3;++iVert)
- {
- ParseVertex(szCurrent,&szCurrent,
- face.avVertices[iVert]);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a float
-bool SMDImporter::ParseFloat(const char* szCurrent,
- const char** szCurrentOut, float& out)
-{
- if (!SkipSpaces(&szCurrent))
- return false;
-
- *szCurrentOut = fast_atof_move(szCurrent,out);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse an unsigned int
-bool SMDImporter::ParseUnsignedInt(const char* szCurrent,
- const char** szCurrentOut, unsigned int& out)
-{
- if (!SkipSpaces(&szCurrent))
- return false;
-
- out = strtol10(szCurrent,szCurrentOut);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a signed int
-bool SMDImporter::ParseSignedInt(const char* szCurrent,
- const char** szCurrentOut, int& out)
-{
- if (!SkipSpaces(&szCurrent))
- return false;
-
- out = strtol10s(szCurrent,szCurrentOut);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a vertex
-void SMDImporter::ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
- bool bVASection /*= false*/)
-{
- if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent))
- {
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
- }
- if (!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
- SMDI_PARSE_RETURN;
- }
-
- if (bVASection)SMDI_PARSE_RETURN;
-
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
- SMDI_PARSE_RETURN;
- }
- if (!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
- SMDI_PARSE_RETURN;
- }
-
- // now read the number of bones affecting this vertex
- // all elements from now are fully optional, we don't need them
- unsigned int iSize = 0;
- if (!ParseUnsignedInt(szCurrent,&szCurrent,iSize))SMDI_PARSE_RETURN;
- vertex.aiBoneLinks.resize(iSize,std::pair<unsigned int, float>(0,0.0f));
-
- for (std::vector<std::pair<unsigned int, float> >::iterator
- i = vertex.aiBoneLinks.begin();
- i != vertex.aiBoneLinks.end();++i)
- {
- if (!ParseUnsignedInt(szCurrent,&szCurrent,(*i).first))
- SMDI_PARSE_RETURN;
- if (!ParseFloat(szCurrent,&szCurrent,(*i).second))
- SMDI_PARSE_RETURN;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER
diff --git a/3rdparty/assimp/code/SMDLoader.h b/3rdparty/assimp/code/SMDLoader.h
deleted file mode 100644
index 0f1cbe8f..00000000
--- a/3rdparty/assimp/code/SMDLoader.h
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file SMDLoader.h
- * @brief Defintion of the Valve SMD file format
- */
-
-#ifndef AI_SMDLOADER_H_INCLUDED
-#define AI_SMDLOADER_H_INCLUDED
-
-// internal headers
-#include "BaseImporter.h"
-#include "ParsingUtils.h"
-
-// public Assimp headers
-#include "../include/aiTypes.h"
-#include "../include/aiTexture.h"
-#include "../include/aiAnim.h"
-#include "../include/aiMaterial.h"
-struct aiNode;
-
-// STL headers
-#include <vector>
-
-namespace Assimp {
-class MaterialHelper;
-
-namespace SMD {
-
-// ---------------------------------------------------------------------------
-/** Data structure for a vertex in a SMD file
-*/
-struct Vertex
-{
- Vertex() : iParentNode(0xffffffff)
- {}
-
- //! Vertex position, normal and texture coordinate
- aiVector3D pos,nor,uv;
-
- //! Vertex parent node
- unsigned int iParentNode;
-
- //! Links to bones: pair.first is the bone index,
- //! pair.second is the vertex weight.
- //! WARN: The remaining weight (to reach 1.0f) is assigned
- //! to the parent node/bone
- std::vector<std::pair<unsigned int, float> > aiBoneLinks;
-};
-
-// ---------------------------------------------------------------------------
-/** Data structure for a face in a SMD file
-*/
-struct Face
-{
- Face() : iTexture(0x0)
- {}
-
- //! Texture index for the face
- unsigned int iTexture;
-
- //! The three vertices of the face
- Vertex avVertices[3];
-};
-
-// ---------------------------------------------------------------------------
-/** Data structure for a bone in a SMD file
-*/
-struct Bone
-{
- //! Default constructor
- Bone() : iParent(0xffffffff), bIsUsed(false)
- {
- }
-
- //! Destructor
- ~Bone()
- {
- }
-
- //! Name of the bone
- std::string mName;
-
- //! Parent of the bone
- uint32_t iParent;
-
- //! Animation of the bone
- struct Animation
- {
- //! Public default constructor
- Animation()
- {
- asKeys.reserve(20);
- }
-
- //! Data structure for a matrix key
- struct MatrixKey
- {
- //! Matrix at this time
- aiMatrix4x4 matrix;
-
- //! Absolute transformation matrix
- aiMatrix4x4 matrixAbsolute;
-
- //! Position
- aiVector3D vPos;
-
- //! Rotation (euler angles)
- aiVector3D vRot;
-
- //! Current time. may be negative, this
- //! will be fixed later
- double dTime;
- };
-
- //! Index of the key with the smallest time value
- uint32_t iFirstTimeKey;
-
- //! Array of matrix keys
- std::vector<MatrixKey> asKeys;
-
- } sAnim;
-
- //! Offset matrix of the bone
- aiMatrix4x4 mOffsetMatrix;
-
- //! true if the bone is referenced by at least one mesh
- bool bIsUsed;
-};
-
-} //! namespace SMD
-
-// ---------------------------------------------------------------------------
-/** Used to load Half-life 1 and 2 SMD models
-*/
-class SMDImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- SMDImporter();
-
- /** Destructor, private as well */
- ~SMDImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Parse the SMD file and create the output scene
- */
- void ParseFile();
-
- // -------------------------------------------------------------------
- /** Parse the triangles section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseTrianglesSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the vertex animation section in VTA files
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseVASection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the nodes section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseNodesSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the skeleton section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseSkeletonSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse a single triangle in the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives the output cursor position
- */
- void ParseTriangle(const char* szCurrent,
- const char** szCurrentOut);
-
-
- // -------------------------------------------------------------------
- /** Parse a single vertex in the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives the output cursor position
- * \param vertex Vertex to be filled
- */
- void ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
- bool bVASection = false);
-
- // -------------------------------------------------------------------
- /** Get the index of a texture. If the texture was not yet known
- * it will be added to the internal texture list.
- * \param filename Name of the texture
- * \return Value texture index
- */
- unsigned int GetTextureIndex(const std::string& filename);
-
- // -------------------------------------------------------------------
- /** Computes absolute bone transformations
- * All output transformations are in worldspace.
- */
- void ComputeAbsoluteBoneTransformations();
-
-
- // -------------------------------------------------------------------
- /** Parse a line in the skeleton section
- */
- void ParseSkeletonElement(const char* szCurrent,
- const char** szCurrentOut,int iTime);
-
- // -------------------------------------------------------------------
- /** Parse a line in the nodes section
- */
- void ParseNodeInfo(const char* szCurrent,
- const char** szCurrentOut);
-
-
- // -------------------------------------------------------------------
- /** Parse a floating-point value
- */
- bool ParseFloat(const char* szCurrent,
- const char** szCurrentOut, float& out);
-
- // -------------------------------------------------------------------
- /** Parse an unsigned integer. There may be no sign!
- */
- bool ParseUnsignedInt(const char* szCurrent,
- const char** szCurrentOut, unsigned int& out);
-
- // -------------------------------------------------------------------
- /** Parse a signed integer. Signs (+,-) are handled.
- */
- bool ParseSignedInt(const char* szCurrent,
- const char** szCurrentOut, int& out);
-
- // -------------------------------------------------------------------
- /** Fix invalid time values in the file
- */
- void FixTimeValues();
-
- // -------------------------------------------------------------------
- /** Add all children of a bone as subnodes to a node
- * \param pcNode Parent node
- * \param iParent Parent bone index
- */
- void AddBoneChildren(aiNode* pcNode, uint32_t iParent);
-
- // -------------------------------------------------------------------
- /** Build output meshes/materials/nodes/animations
- */
- void CreateOutputMeshes();
- void CreateOutputNodes();
- void CreateOutputAnimations();
- void CreateOutputMaterials();
-
-
- // -------------------------------------------------------------------
- /** Print a log message together with the current line number
- */
- void LogErrorNoThrow(const char* msg);
- void LogWarning(const char* msg);
-
-
- // -------------------------------------------------------------------
- inline bool SkipLine( const char* in, const char** out)
- {
- Assimp::SkipLine(in,out);
- ++iLineNumber;
- return true;
- }
- // -------------------------------------------------------------------
- inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
- {
- ++iLineNumber;
- return Assimp::SkipSpacesAndLineEnd(in,out);
- }
-
-private:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Buffer to hold the loaded file */
- const char* mBuffer;
-
- /** Output scene to be filled
- */
- aiScene* pScene;
-
- /** Size of the input file in bytes
- */
- unsigned int iFileSize;
-
- /** Array of textures found in the file
- */
- std::vector<std::string> aszTextures;
-
- /** Array of triangles found in the file
- */
- std::vector<SMD::Face> asTriangles;
-
- /** Array of bones found in the file
- */
- std::vector<SMD::Bone> asBones;
-
- /** Smallest frame index found in the skeleton
- */
- int iSmallestFrame;
-
- /** Length of the whole animation, in frames
- */
- double dLengthOfAnim;
-
- /** Do we have texture coordinates?
- */
- bool bHasUVs;
-
- /** Current line numer
- */
- unsigned int iLineNumber;
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SMDIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/STLLoader.cpp b/3rdparty/assimp/code/STLLoader.cpp
deleted file mode 100644
index 2c8701df..00000000
--- a/3rdparty/assimp/code/STLLoader.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the STL importer class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-
-// internal headers
-#include "STLLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-STLImporter::STLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-STLImporter::~STLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "stl")
- return true;
- else if (!extension.length() || checkSig) {
- if (!pIOHandler)
- return true;
- const char* tokens[] = {"STL","solid"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void STLImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("stl");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void STLImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open STL file " + pFile + ".");
- }
-
- fileSize = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- this->pScene = pScene;
- this->mBuffer = &mBuffer2[0];
-
- // the default vertex color is white
- clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f;
-
- // allocate one mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
- pMesh->mMaterialIndex = 0;
-
- // allocate a single node
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
-
- bool bMatClr = false;
-
- // check whether the file starts with 'solid' -
- // in this case we can simply assume it IS a text file. finished.
- if (!::strncmp(mBuffer,"solid",5)) {
- LoadASCIIFile();
- }
- else bMatClr = LoadBinaryFile();
-
- // now copy faces
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
- for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
-
- aiFace& face = pMesh->mFaces[i];
- face.mIndices = new unsigned int[face.mNumIndices = 3];
- for (unsigned int o = 0; o < 3;++o,++p) {
- face.mIndices[o] = p;
- }
- }
-
- // create a single default material - everything white, as we have vertex colors
- MaterialHelper* pcMat = new MaterialHelper();
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- pcMat->AddProperty(&s, AI_MATKEY_NAME);
-
- aiColor4D clrDiffuse(1.0f,1.0f,1.0f,1.0f);
- if (bMatClr) {
- clrDiffuse = clrColorDefault;
- }
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
- clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
-
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-}
-// ------------------------------------------------------------------------------------------------
-// Read an ASCII STL file
-void STLImporter::LoadASCIIFile()
-{
- aiMesh* pMesh = pScene->mMeshes[0];
-
- const char* sz = mBuffer + 5; // skip the "solid"
- SkipSpaces(&sz);
- const char* szMe = sz;
- while (!::IsSpaceOrNewLine(*sz)) {
- sz++;
- }
-
- size_t temp;
- // setup the name of the node
- if ((temp = (size_t)(sz-szMe))) {
-
- pScene->mRootNode->mName.length = temp;
- memcpy(pScene->mRootNode->mName.data,szMe,temp);
- pScene->mRootNode->mName.data[temp] = '\0';
- }
- else pScene->mRootNode->mName.Set("<STL_ASCII>");
-
- // try to guess how many vertices we could have
- // assume we'll need 160 bytes for each face
- pMesh->mNumVertices = ( pMesh->mNumFaces = fileSize / 160 ) * 3;
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-
- unsigned int curFace = 0, curVertex = 3;
- while (true)
- {
- // go to the next token
- if (!SkipSpacesAndLineEnd(&sz))
- {
- // seems we're finished although there was no end marker
- DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected");
- break;
- }
- // facet normal -0.13 -0.13 -0.98
- if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) {
-
- if (3 != curVertex) {
- DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
- }
- if (pMesh->mNumFaces == curFace) {
- // need to resize the arrays, our size estimate was wrong
- unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
- if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping
- unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize;
- add += add >> 3; // add 12.5% as buffer
- iNeededSize = (pMesh->mNumFaces + add)*3;
- aiVector3D* pv = new aiVector3D[iNeededSize];
- memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
- delete[] pMesh->mVertices;
- pMesh->mVertices = pv;
- pv = new aiVector3D[iNeededSize];
- memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
- delete[] pMesh->mNormals;
- pMesh->mNormals = pv;
-
- pMesh->mNumVertices = iNeededSize;
- pMesh->mNumFaces += add;
- }
- aiVector3D* vn = &pMesh->mNormals[curFace++*3];
-
- sz += 6;
- curVertex = 0;
- SkipSpaces(&sz);
- if (strncmp(sz,"normal",6)) {
- DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
- }
- else
- {
- sz += 7;
- SkipSpaces(&sz);
- sz = fast_atof_move(sz, (float&)vn->x );
- SkipSpaces(&sz);
- sz = fast_atof_move(sz, (float&)vn->y );
- SkipSpaces(&sz);
- sz = fast_atof_move(sz, (float&)vn->z );
- *(vn+1) = *vn;
- *(vn+2) = *vn;
- }
- }
- // vertex 1.50000 1.50000 0.00000
- else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
- {
- if (3 == curVertex) {
- DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
- }
- else
- {
- sz += 7;
- SkipSpaces(&sz);
- aiVector3D* vn = &pMesh->mVertices[(curFace-1)*3 + curVertex++];
- sz = fast_atof_move(sz, (float&)vn->x );
- SkipSpaces(&sz);
- sz = fast_atof_move(sz, (float&)vn->y );
- SkipSpaces(&sz);
- sz = fast_atof_move(sz, (float&)vn->z );
- }
- }
- else if (!::strncmp(sz,"endsolid",8)) {
- // finished!
- break;
- }
- // else skip the whole identifier
- else while (!::IsSpaceOrNewLine(*sz)) {
- ++sz;
- }
- }
-
- if (!curFace) {
- pMesh->mNumFaces = 0;
- throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
- }
- pMesh->mNumFaces = curFace;
- pMesh->mNumVertices = curFace*3;
- // we are finished!
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a binary STL file
-bool STLImporter::LoadBinaryFile()
-{
- // skip the first 80 bytes
- if (fileSize < 84) {
- throw DeadlyImportError("STL: file is too small for the header");
- }
- bool bIsMaterialise = false;
-
- // search for an occurence of "COLOR=" in the header
- const char* sz2 = (const char*)mBuffer;
- const char* const szEnd = sz2+80;
- while (sz2 < szEnd) {
-
- if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
- 'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++) {
-
- // read the default vertex color for facets
- bIsMaterialise = true;
- DefaultLogger::get()->info("STL: Taking code path for Materialise files");
- clrColorDefault.r = (*sz2++) / 255.0f;
- clrColorDefault.g = (*sz2++) / 255.0f;
- clrColorDefault.b = (*sz2++) / 255.0f;
- clrColorDefault.a = (*sz2++) / 255.0f;
- break;
- }
- }
- const unsigned char* sz = (const unsigned char*)mBuffer + 80;
-
- // now read the number of facets
- aiMesh* pMesh = pScene->mMeshes[0];
- pScene->mRootNode->mName.Set("<STL_BINARY>");
-
- pMesh->mNumFaces = *((uint32_t*)sz);
- sz += 4;
-
- if (fileSize < 84 + pMesh->mNumFaces*50) {
- throw DeadlyImportError("STL: file is too small to hold all facets");
- }
-
- if (!pMesh->mNumFaces) {
- throw DeadlyImportError("STL: file is empty. There are no facets defined");
- }
-
- pMesh->mNumVertices = pMesh->mNumFaces*3;
-
- aiVector3D* vp,*vn;
- vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-
- for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
-
- // NOTE: Blender sometimes writes empty normals ... this is not
- // our fault ... the RemoveInvalidData helper step should fix that
- *vn = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
- *(vn+1) = *vn;
- *(vn+2) = *vn;
- vn += 3;
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- uint16_t color = *((uint16_t*)sz);
- sz += 2;
-
- if (color & (1 << 15))
- {
- // seems we need to take the color
- if (!pMesh->mColors[0])
- {
- pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
- for (unsigned int i = 0; i <pMesh->mNumVertices;++i)
- *pMesh->mColors[0]++ = this->clrColorDefault;
- pMesh->mColors[0] -= pMesh->mNumVertices;
-
- DefaultLogger::get()->info("STL: Mesh has vertex colors");
- }
- aiColor4D* clr = &pMesh->mColors[0][pMesh->mNumFaces*3];
- clr->a = 1.0f;
- if (bIsMaterialise) // fuck, this is reversed
- {
- clr->r = (color & 0x31u) / 31.0f;
- clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
- clr->b = ((color & (0x31u<<10))>>10u) / 31.0f;
- }
- else
- {
- clr->b = (color & 0x31u) / 31.0f;
- clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
- clr->r = ((color & (0x31u<<10))>>10u) / 31.0f;
- }
- // assign the color to all vertices of the face
- *(clr+1) = *clr;
- *(clr+2) = *clr;
- }
- }
- if (bIsMaterialise && !pMesh->mColors[0])
- {
- // use the color as diffuse material color
- return true;
- }
- return false;
-}
-
-#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
diff --git a/3rdparty/assimp/code/STLLoader.h b/3rdparty/assimp/code/STLLoader.h
deleted file mode 100644
index bdaacfe1..00000000
--- a/3rdparty/assimp/code/STLLoader.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file STLLoader.h
- * Declaration of the STL importer class.
- */
-#ifndef AI_STLLOADER_H_INCLUDED
-#define AI_STLLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "../include/aiTypes.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the sterolithography STL file format
-*/
-class STLImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- STLImporter();
-
- /** Destructor, private as well */
- ~STLImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
- // -------------------------------------------------------------------
- /** Loads a binary .stl file
- * @return true if the default vertex color must be used as material color
- */
- bool LoadBinaryFile();
-
- // -------------------------------------------------------------------
- /** Loads a ASCII text .stl file
- */
- void LoadASCIIFile();
-
-protected:
-
- /** Buffer to hold the loaded file */
- const char* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Output scene */
- aiScene* pScene;
-
- /** Default vertex color */
- aiColor4D clrColorDefault;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/3rdparty/assimp/code/SceneCombiner.cpp b/3rdparty/assimp/code/SceneCombiner.cpp
deleted file mode 100644
index 7ee40fd3..00000000
--- a/3rdparty/assimp/code/SceneCombiner.cpp
+++ /dev/null
@@ -1,1133 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-// ----------------------------------------------------------------------------
-/** @file Implements Assimp::SceneCombiner. This is a smart utility
- * class that combines multiple scenes, meshes, ... into one. Currently
- * these utilities are used by the IRR and LWS loaders and the
- * OptimizeGraph step.
- */
-// ----------------------------------------------------------------------------
-#include "AssimpPCH.h"
-#include "SceneCombiner.h"
-#include "fast_atof.h"
-#include "Hash.h"
-#include "time.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Add a prefix to a string
-inline void PrefixString(aiString& string,const char* prefix, unsigned int len)
-{
- // If the string is already prefixed, we won't prefix it a second time
- if (string.length >= 1 && string.data[0] == '$')
- return;
-
- if (len+string.length>=MAXLEN-1) {
- DefaultLogger::get()->debug("Can't add an unique prefix because the string is too long");
- ai_assert(false);
- return;
- }
-
- // Add the prefix
- ::memmove(string.data+len,string.data,string.length+1);
- ::memcpy (string.data, prefix, len);
-
- // And update the string's length
- string.length += len;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add node identifiers to a hashing set
-void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes)
-{
- // Add node name to hashing set if it is non-empty - empty nodes are allowed
- // and they can't have any anims assigned so its absolutely safe to duplicate them.
- if (node->mName.length) {
- hashes.insert( SuperFastHash(node->mName.data,node->mName.length) );
- }
-
- // Process all children recursively
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- AddNodeHashes(node->mChildren[i],hashes);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a name prefix to all nodes in a hierarchy
-void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len)
-{
- ai_assert(NULL != prefix);
- PrefixString(node->mName,prefix,len);
-
- // Process all children recursively
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- AddNodePrefixes(node->mChildren[i],prefix,len);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search for matching names
-bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur)
-{
- const unsigned int hash = SuperFastHash(name.data, name.length);
-
- // Check whether we find a positive match in one of the given sets
- for (unsigned int i = 0; i < input.size(); ++i) {
-
- if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
- return true;
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a name prefix to all nodes in a hierarchy if a hash match is found
-void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, unsigned int len,
- std::vector<SceneHelper>& input, unsigned int cur)
-{
- ai_assert(NULL != prefix);
- const unsigned int hash = SuperFastHash(node->mName.data,node->mName.length);
-
- // Check whether we find a positive match in one of the given sets
- for (unsigned int i = 0; i < input.size(); ++i) {
-
- if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
- PrefixString(node->mName,prefix,len);
- break;
- }
- }
-
- // Process all children recursively
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- AddNodePrefixesChecked(node->mChildren[i],prefix,len,input,cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add an offset to all mesh indices in a node graph
-void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset)
-{
- for (unsigned int i = 0; i < node->mNumMeshes;++i)
- node->mMeshes[i] += offset;
-
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- OffsetNodeMeshIndices(node->mChildren[i],offset);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merges two scenes. Currently only used by the LWS loader.
-void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
- unsigned int flags)
-{
- ai_assert(NULL != _dest);
-
- // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
- if (src.empty())
- {
- if (*_dest)
- {
- (*_dest)->~aiScene();
- SceneCombiner::CopySceneFlat(_dest,src[0]);
- }
- else *_dest = src[0];
- return;
- }
- if (*_dest)(*_dest)->~aiScene();
- else *_dest = new aiScene();
-
- // Create a dummy scene to serve as master for the others
- aiScene* master = new aiScene();
- master->mRootNode = new aiNode();
- master->mRootNode->mName.Set("<MergeRoot>");
-
- std::vector<AttachmentInfo> srcList (src.size());
- for (unsigned int i = 0; i < srcList.size();++i) {
- srcList[i] = AttachmentInfo(src[i],master->mRootNode);
- }
-
- // 'master' will be deleted afterwards
- MergeScenes (_dest, master, srcList, flags);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList)
-{
- unsigned int cnt;
- for (cnt = 0; cnt < attach->mNumChildren;++cnt)
- AttachToGraph(attach->mChildren[cnt],srcList);
-
- cnt = 0;
- for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin();
- it != srcList.end(); ++it)
- {
- if ((*it).attachToNode == attach && !(*it).resolved)
- ++cnt;
- }
-
- if (cnt) {
- aiNode** n = new aiNode*[cnt+attach->mNumChildren];
- if (attach->mNumChildren) {
- ::memcpy(n,attach->mChildren,sizeof(void*)*attach->mNumChildren);
- delete[] attach->mChildren;
- }
- attach->mChildren = n;
-
- n += attach->mNumChildren;
- attach->mNumChildren += cnt;
-
- for (unsigned int i = 0; i < srcList.size();++i) {
- NodeAttachmentInfo& att = srcList[i];
- if (att.attachToNode == attach && !att.resolved) {
- *n = att.node;
- (**n).mParent = attach;
- ++n;
-
- // mark this attachment as resolved
- att.resolved = true;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::AttachToGraph ( aiScene* master,
- std::vector<NodeAttachmentInfo>& src)
-{
- ai_assert(NULL != master);
- AttachToGraph(master->mRootNode,src);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
- std::vector<AttachmentInfo>& srcList,
- unsigned int flags)
-{
- ai_assert(NULL != _dest);
-
- // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
- if (srcList.empty())
- {
- if (*_dest)
- {
- (*_dest)->~aiScene();
- SceneCombiner::CopySceneFlat(_dest,master);
- }
- else *_dest = master;
- return;
- }
- if (*_dest)(*_dest)->~aiScene();
- else *_dest = new aiScene();
-
- aiScene* dest = *_dest;
-
- std::vector<SceneHelper> src (srcList.size()+1);
- src[0].scene = master;
- for (unsigned int i = 0; i < srcList.size();++i) {
- src[i+1] = SceneHelper( srcList[i].scene );
- }
-
- // this helper array specifies which scenes are duplicates of others
- std::vector<unsigned int> duplicates(src.size(),0xffffffff);
-
- // this helper array is used as lookup table several times
- std::vector<unsigned int> offset(src.size());
-
- // Find duplicate scenes
- for (unsigned int i = 0; i < src.size();++i)
- {
- if (duplicates[i] != i && duplicates[i] != 0xffffffff)continue;
- duplicates[i] = i;
- for ( unsigned int a = i+1; a < src.size(); ++a)
- {
- if (src[i].scene == src[a].scene)
- duplicates[a] = i;
- }
- }
-
- // Generate unique names for all named stuff?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES)
- {
-#if 0
- // Construct a proper random number generator
- boost::mt19937 rng( );
- boost::uniform_int<> dist(1u,1 << 24u);
- boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rndGen(rng, dist);
-#endif
- for (unsigned int i = 1; i < src.size();++i)
- {
- //if (i != duplicates[i])
- //{
- // // duplicate scenes share the same UID
- // ::strcpy( src[i].id, src[duplicates[i]].id );
- // src[i].idlen = src[duplicates[i]].idlen;
-
- // continue;
- //}
-
- src[i].idlen = ::sprintf(src[i].id,"$%.6X$_",i);
-
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
-
- // Compute hashes for all identifiers in this scene and store them
- // in a sorted table (for convenience I'm using std::set). We hash
- // just the node and animation channel names, all identifiers except
- // the material names should be caught by doing this.
- AddNodeHashes(src[i]->mRootNode,src[i].hashes);
-
- for (unsigned int a = 0; a < src[i]->mNumAnimations;++a) {
- aiAnimation* anim = src[i]->mAnimations[a];
- src[i].hashes.insert(SuperFastHash(anim->mName.data,anim->mName.length));
- }
- }
- }
- }
-
- unsigned int cnt;
-
- // First find out how large the respective output arrays must be
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
-
- if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
- dest->mNumTextures += (*cur)->mNumTextures;
- dest->mNumMaterials += (*cur)->mNumMaterials;
- dest->mNumMeshes += (*cur)->mNumMeshes;
- }
-
- dest->mNumLights += (*cur)->mNumLights;
- dest->mNumCameras += (*cur)->mNumCameras;
- dest->mNumAnimations += (*cur)->mNumAnimations;
-
- // Combine the flags of all scenes
- // We need to process them flag-by-flag here to get correct results
- // dest->mFlags ; //|= (*cur)->mFlags;
- if ((*cur)->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
- dest->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- }
- }
-
- // generate the output texture list + an offset table for all texture indices
- if (dest->mNumTextures)
- {
- aiTexture** pip = dest->mTextures = new aiTexture*[dest->mNumMaterials];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumTextures;++i)
- {
- if (n != duplicates[n])
- {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip,(*cur)->mTextures[i]);
-
- else continue;
- }
- else *pip = (*cur)->mTextures[i];
- ++pip;
- }
-
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mTextures);
- }
- }
-
- // generate the output material list + an offset table for all material indices
- if (dest->mNumMaterials)
- {
- aiMaterial** pip = dest->mMaterials = new aiMaterial*[dest->mNumMaterials];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n ) {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumMaterials;++i)
- {
- if (n != duplicates[n])
- {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip,(*cur)->mMaterials[i]);
-
- else continue;
- }
- else *pip = (*cur)->mMaterials[i];
-
- if ((*cur)->mNumTextures != dest->mNumTextures) {
- // We need to update all texture indices of the mesh. So we need to search for
- // a material property called '$tex.file'
-
- for (unsigned int a = 0; a < (*pip)->mNumProperties;++a)
- {
- aiMaterialProperty* prop = (*pip)->mProperties[a];
- if (!strncmp(prop->mKey.data,"$tex.file",9))
- {
- // Check whether this texture is an embedded texture.
- // In this case the property looks like this: *<n>,
- // where n is the index of the texture.
- aiString& s = *((aiString*)prop->mData);
- if ('*' == s.data[0]) {
- // Offset the index and write it back ..
- const unsigned int idx = strtol10(&s.data[1]) + offset[n];
- ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx);
- }
- }
-
- // Need to generate new, unique material names?
- else if (!::strcmp( prop->mKey.data,"$mat.name" ) && flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES)
- {
- aiString* pcSrc = (aiString*) prop->mData;
- PrefixString(*pcSrc, (*cur).id, (*cur).idlen);
- }
- }
- }
- ++pip;
- }
-
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mMaterials);
- }
- }
-
- // generate the output mesh list + again an offset table for all mesh indices
- if (dest->mNumMeshes)
- {
- aiMesh** pip = dest->mMeshes = new aiMesh*[dest->mNumMeshes];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i)
- {
- if (n != duplicates[n]) {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip, (*cur)->mMeshes[i]);
-
- else continue;
- }
- else *pip = (*cur)->mMeshes[i];
-
- // update the material index of the mesh
- (*pip)->mMaterialIndex += offset[n];
- ++pip;
- }
-
- // reuse the offset array - store now the mesh offset in it
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mMeshes);
- }
- }
-
- std::vector <NodeAttachmentInfo> nodes;
- nodes.reserve(srcList.size());
-
- // ----------------------------------------------------------------------------
- // Now generate the output node graph. We need to make those
- // names in the graph that are referenced by anims or lights
- // or cameras unique. So we add a prefix to them ... $<rand>_
- // We could also use a counter, but using a random value allows us to
- // use just one prefix if we are joining multiple scene hierarchies recursively.
- // Chances are quite good we don't collide, so we try that ...
- // ----------------------------------------------------------------------------
-
- // Allocate space for light sources, cameras and animations
- aiLight** ppLights = dest->mLights = (dest->mNumLights
- ? new aiLight*[dest->mNumLights] : NULL);
-
- aiCamera** ppCameras = dest->mCameras = (dest->mNumCameras
- ? new aiCamera*[dest->mNumCameras] : NULL);
-
- aiAnimation** ppAnims = dest->mAnimations = (dest->mNumAnimations
- ? new aiAnimation*[dest->mNumAnimations] : NULL);
-
- for ( int n = src.size()-1; n >= 0 ;--n ) /* !!! important !!! */
- {
- SceneHelper* cur = &src[n];
- aiNode* node;
-
- // To offset or not to offset, this is the question
- if (n != (int)duplicates[n])
- {
- // Get full scenegraph copy
- Copy( &node, (*cur)->mRootNode );
- OffsetNodeMeshIndices(node,offset[duplicates[n]]);
-
- if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
- // (note:) they are already 'offseted' by offset[duplicates[n]]
- OffsetNodeMeshIndices(node,offset[n] - offset[duplicates[n]]);
- }
- }
- else // if (n == duplicates[n])
- {
- node = (*cur)->mRootNode;
- OffsetNodeMeshIndices(node,offset[n]);
- }
- if (n) // src[0] is the master node
- nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode,n ));
-
- // add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
-
- // or the whole scenegraph
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- AddNodePrefixesChecked(node,(*cur).id,(*cur).idlen,src,n);
- }
- else AddNodePrefixes(node,(*cur).id,(*cur).idlen);
-
- // meshes
- for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i) {
- aiMesh* mesh = (*cur)->mMeshes[i];
-
- // rename all bones
- for (unsigned int a = 0; a < mesh->mNumBones;++a) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch(mesh->mBones[a]->mName,src,n))
- continue;
- }
- PrefixString(mesh->mBones[a]->mName,(*cur).id,(*cur).idlen);
- }
- }
- }
-
- // --------------------------------------------------------------------
- // Copy light sources
- for (unsigned int i = 0; i < (*cur)->mNumLights;++i,++ppLights)
- {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppLights, (*cur)->mLights[i]);
- }
- else *ppLights = (*cur)->mLights[i];
-
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppLights)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppLights)->mName,(*cur).id,(*cur).idlen);
- }
- }
-
- // --------------------------------------------------------------------
- // Copy cameras
- for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras) {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppCameras, (*cur)->mCameras[i]);
- }
- else *ppCameras = (*cur)->mCameras[i];
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppCameras)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppCameras)->mName,(*cur).id,(*cur).idlen);
- }
- }
-
- // --------------------------------------------------------------------
- // Copy animations
- for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims) {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppAnims, (*cur)->mAnimations[i]);
- }
- else *ppAnims = (*cur)->mAnimations[i];
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppAnims)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppAnims)->mName,(*cur).id,(*cur).idlen);
-
- // don't forget to update all node animation channels
- for (unsigned int a = 0; a < (*ppAnims)->mNumChannels;++a) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppAnims)->mChannels[a]->mNodeName,src,n))
- continue;
- }
-
- PrefixString((*ppAnims)->mChannels[a]->mNodeName,(*cur).id,(*cur).idlen);
- }
- }
- }
- }
-
- // Now build the output graph
- AttachToGraph ( master, nodes);
- dest->mRootNode = master->mRootNode;
-
- // Check whether we succeeded at building the output graph
- for (std::vector <NodeAttachmentInfo> ::iterator it = nodes.begin();
- it != nodes.end(); ++it)
- {
- if (!(*it).resolved) {
- if (flags & AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS) {
- // search for this attachment point in all other imported scenes, too.
- for ( unsigned int n = 0; n < src.size();++n ) {
- if (n != (*it).src_idx) {
- AttachToGraph(src[n].scene,nodes);
- if ((*it).resolved)
- break;
- }
- }
- }
- if (!(*it).resolved) {
- DefaultLogger::get()->error(std::string("SceneCombiner: Failed to resolve attachment ")
- + (*it).node->mName.data + " " + (*it).attachToNode->mName.data);
- }
- }
- }
-
- // now delete all input scenes. Make sure duplicate scenes aren't
- // deleted more than one time
- for ( unsigned int n = 0; n < src.size();++n ) {
- if (n != duplicates[n]) // duplicate scene?
- continue;
-
- aiScene* deleteMe = src[n].scene;
-
- // We need to delete the arrays before the destructor is called -
- // we are reusing the array members
- delete[] deleteMe->mMeshes; deleteMe->mMeshes = NULL;
- delete[] deleteMe->mCameras; deleteMe->mCameras = NULL;
- delete[] deleteMe->mLights; deleteMe->mLights = NULL;
- delete[] deleteMe->mMaterials; deleteMe->mMaterials = NULL;
- delete[] deleteMe->mAnimations; deleteMe->mAnimations = NULL;
-
- deleteMe->mRootNode = NULL;
-
- // Now we can safely delete the scene
- delete deleteMe;
- }
-
- // Check flags
- if (!dest->mNumMeshes || !dest->mNumMaterials) {
- dest->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- // We're finished
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a list of unique bones
-void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
- std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end)
-{
- unsigned int iOffset = 0;
- for (; it != end;++it) {
- for (unsigned int l = 0; l < (*it)->mNumBones;++l) {
- aiBone* p = (*it)->mBones[l];
- uint32_t itml = SuperFastHash(p->mName.data,(unsigned int)p->mName.length);
-
- std::list<BoneWithHash>::iterator it2 = asBones.begin();
- std::list<BoneWithHash>::iterator end2 = asBones.end();
-
- for (;it2 != end2;++it2) {
- if ((*it2).first == itml) {
- (*it2).pSrcBones.push_back(BoneSrcIndex(p,iOffset));
- break;
- }
- }
- if (end2 == it2) {
- // need to begin a new bone entry
- asBones.push_back(BoneWithHash());
- BoneWithHash& btz = asBones.back();
-
- // setup members
- btz.first = itml;
- btz.second = &p->mName;
- btz.pSrcBones.push_back(BoneSrcIndex(p,iOffset));
- }
- }
- iOffset += (*it)->mNumVertices;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merge a list of bones
-void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end)
-{
- ai_assert(NULL != out && !out->mNumBones);
-
- // find we need to build an unique list of all bones.
- // we work with hashes to make the comparisons MUCH faster,
- // at least if we have many bones.
- std::list<BoneWithHash> asBones;
- BuildUniqueBoneList(asBones, it,end);
-
- // now create the output bones
- out->mNumBones = 0;
- out->mBones = new aiBone*[asBones.size()];
-
- for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it) {
- // Allocate a bone and setup it's name
- aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
- pc->mName = aiString( *((*it).second ));
-
- std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end();
-
- // Loop through all bones to be joined for this bone
- for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
- pc->mNumWeights += (*wmit).first->mNumWeights;
-
- // NOTE: different offset matrices for bones with equal names
- // are - at the moment - not handled correctly.
- if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix) {
- DefaultLogger::get()->warn("Bones with equal names but different offset matrices can't be joined at the moment");
- continue;
- }
- pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix;
- }
-
- // Allocate the vertex weight array
- aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- // And copy the final weights - adjust the vertex IDs by the
- // face index offset of the coresponding mesh.
- for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
- aiBone* pip = (*wmit).first;
- for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
- const aiVertexWeight& vfi = pip->mWeights[mp];
- avw->mWeight = vfi.mWeight;
- avw->mVertexId = vfi.mVertexId + (*wmit).second;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merge a list of meshes
-void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
- std::vector<aiMesh*>::const_iterator begin,
- std::vector<aiMesh*>::const_iterator end)
-{
- ai_assert(NULL != _out);
-
- if (begin == end) {
- *_out = NULL; // no meshes ...
- return;
- }
-
- // Allocate the output mesh
- aiMesh* out = *_out = new aiMesh();
- out->mMaterialIndex = (*begin)->mMaterialIndex;
-
- // Find out how much output storage we'll need
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- out->mNumVertices += (*it)->mNumVertices;
- out->mNumFaces += (*it)->mNumFaces;
- out->mNumBones += (*it)->mNumBones;
-
- // combine primitive type flags
- out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
- }
-
- if (out->mNumVertices) {
- aiVector3D* pv2;
-
- // copy vertex positions
- if ((**begin).HasPositions()) {
-
- pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- if ((*it)->mVertices) {
- ::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Positions expected but input mesh contains no positions");
- pv2 += (*it)->mNumVertices;
- }
- }
- // copy normals
- if ((**begin).HasNormals()) {
-
- pv2 = out->mNormals = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- if ((*it)->mNormals) {
- ::memcpy(pv2,(*it)->mNormals,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Normals expected but input mesh contains no normals");
- pv2 += (*it)->mNumVertices;
- }
- }
- // copy tangents and bitangents
- if ((**begin).HasTangentsAndBitangents()) {
-
- pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
- aiVector3D* pv2b = out->mBitangents = new aiVector3D[out->mNumVertices];
-
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- if ((*it)->mTangents) {
- ::memcpy(pv2, (*it)->mTangents, (*it)->mNumVertices*sizeof(aiVector3D));
- ::memcpy(pv2b,(*it)->mBitangents,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Tangents expected but input mesh contains no tangents");
- pv2 += (*it)->mNumVertices;
- pv2b += (*it)->mNumVertices;
- }
- }
- // copy texture coordinates
- unsigned int n = 0;
- while ((**begin).HasTextureCoords(n)) {
- out->mNumUVComponents[n] = (*begin)->mNumUVComponents[n];
-
- pv2 = out->mTextureCoords[n] = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
-
- if ((*it)->mTextureCoords[n]) {
- ::memcpy(pv2,(*it)->mTextureCoords[n],(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: UVs expected but input mesh contains no UVs");
- pv2 += (*it)->mNumVertices;
- }
- ++n;
- }
- // copy vertex colors
- n = 0;
- while ((**begin).HasVertexColors(n)) {
- aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
-
- if ((*it)->mColors[n]) {
- ::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: VCs expected but input mesh contains no VCs");
- pv2 += (*it)->mNumVertices;
- }
- ++n;
- }
- }
-
- if (out->mNumFaces) // just for safety
- {
- // copy faces
- out->mFaces = new aiFace[out->mNumFaces];
- aiFace* pf2 = out->mFaces;
-
- unsigned int ofs = 0;
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- for (unsigned int m = 0; m < (*it)->mNumFaces;++m,++pf2) {
- aiFace& face = (*it)->mFaces[m];
- pf2->mNumIndices = face.mNumIndices;
- pf2->mIndices = face.mIndices;
-
- if (ofs) {
- // add the offset to the vertex
- for (unsigned int q = 0; q < face.mNumIndices; ++q)
- face.mIndices[q] += ofs;
- }
- face.mIndices = NULL;
- }
- ofs += (*it)->mNumVertices;
- }
- }
-
- // bones - as this is quite lengthy, I moved the code to a separate function
- if (out->mNumBones)
- MergeBones(out,begin,end);
-
- // delete all source meshes
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)
- delete *it;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename Type>
-inline void CopyPtrArray (Type**& dest, Type** src, unsigned int num)
-{
- if (!num)
- {
- dest = NULL;
- return;
- }
- dest = new Type*[num];
- for (unsigned int i = 0; i < num;++i)
- SceneCombiner::Copy(&dest[i],src[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename Type>
-inline void GetArrayCopy (Type*& dest, unsigned int num )
-{
- if (!dest)return;
- Type* old = dest;
-
- dest = new Type[num];
- ::memcpy(dest, old, sizeof(Type) * num);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::CopySceneFlat(aiScene** _dest,aiScene* src)
-{
- // reuse the old scene or allocate a new?
- if (*_dest)(*_dest)->~aiScene();
- else *_dest = new aiScene();
-
- ::memcpy(*_dest,src,sizeof(aiScene));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::CopyScene(aiScene** _dest,aiScene* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiScene* dest = *_dest = new aiScene();
-
- // copy animations
- dest->mNumAnimations = src->mNumAnimations;
- CopyPtrArray(dest->mAnimations,src->mAnimations,
- dest->mNumAnimations);
-
- // copy textures
- dest->mNumTextures = src->mNumTextures;
- CopyPtrArray(dest->mTextures,src->mTextures,
- dest->mNumTextures);
-
- // copy materials
- dest->mNumMaterials = src->mNumMaterials;
- CopyPtrArray(dest->mMaterials,src->mMaterials,
- dest->mNumMaterials);
-
- // copy lights
- dest->mNumLights = src->mNumLights;
- CopyPtrArray(dest->mLights,src->mLights,
- dest->mNumLights);
-
- // copy cameras
- dest->mNumCameras = src->mNumCameras;
- CopyPtrArray(dest->mCameras,src->mCameras,
- dest->mNumCameras);
-
- // copy meshes
- dest->mNumMeshes = src->mNumMeshes;
- CopyPtrArray(dest->mMeshes,src->mMeshes,
- dest->mNumMeshes);
-
- // now - copy the root node of the scene (deep copy, too)
- Copy( &dest->mRootNode, src->mRootNode);
-
- // and keep the flags ...
- dest->mFlags = src->mFlags;
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiMesh** _dest, const aiMesh* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiMesh* dest = *_dest = new aiMesh();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiMesh));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mVertices, dest->mNumVertices );
- GetArrayCopy( dest->mNormals , dest->mNumVertices );
- GetArrayCopy( dest->mTangents, dest->mNumVertices );
- GetArrayCopy( dest->mBitangents, dest->mNumVertices );
-
- unsigned int n = 0;
- while (dest->HasTextureCoords(n))
- GetArrayCopy( dest->mTextureCoords[n++], dest->mNumVertices );
-
- n = 0;
- while (dest->HasVertexColors(n))
- GetArrayCopy( dest->mColors[n++], dest->mNumVertices );
-
- // make a deep copy of all bones
- CopyPtrArray(dest->mBones,dest->mBones,dest->mNumBones);
-
- // make a deep copy of all faces
- GetArrayCopy(dest->mFaces,dest->mNumFaces);
- for (unsigned int i = 0; i < dest->mNumFaces;++i)
- {
- aiFace& f = dest->mFaces[i];
- GetArrayCopy(f.mIndices,f.mNumIndices);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- MaterialHelper* dest = (MaterialHelper*) ( *_dest = new MaterialHelper() );
- dest->mNumAllocated = src->mNumAllocated;
- dest->mNumProperties = src->mNumProperties;
- dest->mProperties = new aiMaterialProperty* [dest->mNumAllocated];
-
- for (unsigned int i = 0; i < dest->mNumProperties;++i)
- {
- aiMaterialProperty* prop = dest->mProperties[i] = new aiMaterialProperty();
- aiMaterialProperty* sprop = src->mProperties[i];
-
- prop->mDataLength = sprop->mDataLength;
- prop->mData = new char[prop->mDataLength];
- ::memcpy(prop->mData,sprop->mData,prop->mDataLength);
-
- prop->mIndex = sprop->mIndex;
- prop->mSemantic = sprop->mSemantic;
- prop->mKey = sprop->mKey;
- prop->mType = sprop->mType;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiTexture** _dest, const aiTexture* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiTexture* dest = *_dest = new aiTexture();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiTexture));
-
- // and reallocate all arrays. We must do it manually here
- const char* old = (const char*)dest->pcData;
- if (old)
- {
- unsigned int cpy;
- if (!dest->mHeight)cpy = dest->mWidth;
- else cpy = dest->mHeight * dest->mWidth * sizeof(aiTexel);
-
- if (!cpy)
- {
- dest->pcData = NULL;
- return;
- }
- // the cast is legal, the aiTexel c'tor does nothing important
- dest->pcData = (aiTexel*) new char[cpy];
- ::memcpy(dest->pcData, old, cpy);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiAnimation** _dest, const aiAnimation* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiAnimation* dest = *_dest = new aiAnimation();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiAnimation));
-
- // and reallocate all arrays
- CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiNodeAnim** _dest, const aiNodeAnim* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiNodeAnim* dest = *_dest = new aiNodeAnim();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiNodeAnim));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys );
- GetArrayCopy( dest->mScalingKeys, dest->mNumScalingKeys );
- GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiCamera** _dest,const aiCamera* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiCamera* dest = *_dest = new aiCamera();
-
- // get a flat copy, that's already OK
- ::memcpy(dest,src,sizeof(aiCamera));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiLight** _dest, const aiLight* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiLight* dest = *_dest = new aiLight();
-
- // get a flat copy, that's already OK
- ::memcpy(dest,src,sizeof(aiLight));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiBone** _dest, const aiBone* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiBone* dest = *_dest = new aiBone();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiBone));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mWeights, dest->mNumWeights );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiNode* dest = *_dest = new aiNode();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiNode));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mMeshes, dest->mNumMeshes );
- CopyPtrArray( dest->mChildren, src->mChildren,dest->mNumChildren);
-}
-
-
-}
diff --git a/3rdparty/assimp/code/SceneCombiner.h b/3rdparty/assimp/code/SceneCombiner.h
deleted file mode 100644
index 8c29c8fd..00000000
--- a/3rdparty/assimp/code/SceneCombiner.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Declares a helper class, "SceneCombiner" providing various
- * utilities to merge scenes.
- */
-#ifndef AI_SCENE_COMBINER_H_INC
-#define AI_SCENE_COMBINER_H_INC
-
-#include "../include/aiAssert.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper data structure for SceneCombiner.
- *
- * Describes to which node a scene must be attached to.
- */
-struct AttachmentInfo
-{
- AttachmentInfo()
- : scene (NULL)
- , attachToNode (NULL)
- {}
-
- AttachmentInfo(aiScene* _scene, aiNode* _attachToNode)
- : scene (_scene)
- , attachToNode (_attachToNode)
- {}
-
- aiScene* scene;
- aiNode* attachToNode;
-};
-
-// ---------------------------------------------------------------------------
-struct NodeAttachmentInfo
-{
- NodeAttachmentInfo()
- : node (NULL)
- , attachToNode (NULL)
- , resolved (false)
- , src_idx (0xffffffff)
- {}
-
- NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx)
- : node (_scene)
- , attachToNode (_attachToNode)
- , resolved (false)
- , src_idx (idx)
- {}
-
- aiNode* node;
- aiNode* attachToNode;
- bool resolved;
- size_t src_idx;
-};
-
-// ---------------------------------------------------------------------------
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES
- * Generate unique names for all named scene items
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1
-
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES
- * Generate unique names for materials, too.
- * This is not absolutely required to pass the validation.
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2
-
-/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY
- * Use deep copies of duplicate scenes
- */
-#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4
-
-/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS
- * If attachment nodes are not found in the given master scene,
- * search the other imported scenes for them in an any order.
- */
-#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8
-
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY
- * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES.
- * Unique names are generated, but only if this is absolutely
- * required to avoid name conflicts.
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
-
-
-typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
-
-// ---------------------------------------------------------------------------
-/** @brief Helper data structure for SceneCombiner::MergeBones.
- */
-struct BoneWithHash : public std::pair<uint32_t,aiString*> {
- std::vector<BoneSrcIndex> pSrcBones;
-};
-
-
-// ---------------------------------------------------------------------------
-/** @brief Utility for SceneCombiner
- */
-struct SceneHelper
-{
- SceneHelper ()
- : scene (NULL)
- , idlen (0)
- {
- id[0] = 0;
- }
-
- SceneHelper (aiScene* _scene)
- : scene (_scene)
- , idlen (0)
- {
- id[0] = 0;
- }
-
- AI_FORCE_INLINE aiScene* operator-> () const
- {
- return scene;
- }
-
- // scene we're working on
- aiScene* scene;
-
- // prefix to be added to all identifiers in the scene ...
- char id [32];
-
- // and its strlen()
- unsigned int idlen;
-
- // hash table to quickly check whether a name is contained in the scene
- std::set<unsigned int> hashes;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Static helper class providing various utilities to merge two
- * scenes. It is intended as internal utility and NOT for use by
- * applications.
- *
- * The class is currently being used by various postprocessing steps
- * and loaders (ie. LWS).
- */
-class ASSIMP_API SceneCombiner
-{
- // class cannot be instanced
- SceneCombiner() {}
-
-public:
-
- // -------------------------------------------------------------------
- /** Merges two or more scenes.
- *
- * @param dest Receives a pointer to the destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param src Non-empty list of scenes to be merged. The function
- * deletes the input scenes afterwards. There may be duplicate scenes.
- * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
- */
- static void MergeScenes(aiScene** dest,std::vector<aiScene*>& src,
- unsigned int flags = 0);
-
-
- // -------------------------------------------------------------------
- /** Merges two or more scenes and attaches all sceenes to a specific
- * position in the node graph of the masteer scene.
- *
- * @param dest Receives a pointer to the destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param master Master scene. It will be deleted afterwards. All
- * other scenes will be inserted in its node graph.
- * @param src Non-empty list of scenes to be merged along with their
- * corresponding attachment points in the master scene. The function
- * deletes the input scenes afterwards. There may be duplicate scenes.
- * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
- */
- static void MergeScenes(aiScene** dest, aiScene* master,
- std::vector<AttachmentInfo>& src,
- unsigned int flags = 0);
-
-
- // -------------------------------------------------------------------
- /** Merges two or more meshes
- *
- * The meshes should have equal vertex formats. Only components
- * that are provided by ALL meshes will be present in the output mesh.
- * An exception is made for VColors - they are set to black. The
- * meshes should have the same material indices, too. The output
- * material index is always the material index of the first mesh.
- *
- * @param dest Destination mesh. Must be empty.
- * @param flags Currently no parameters
- * @param begin First mesh to be processed
- * @param end Points to the mesh after the last mesh to be processed
- */
- static void MergeMeshes(aiMesh** dest,unsigned int flags,
- std::vector<aiMesh*>::const_iterator begin,
- std::vector<aiMesh*>::const_iterator end);
-
-
- // -------------------------------------------------------------------
- /** Merges two or more bones
- *
- * @param out Mesh to receive the output bone list
- * @param flags Currently no parameters
- * @param begin First mesh to be processed
- * @param end Points to the mesh after the last mesh to be processed
- */
- static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end);
-
-
- // -------------------------------------------------------------------
- /** Builds a list of uniquely named bones in a mesh list
- *
- * @param asBones Receives the output list
- * @param it First mesh to be processed
- * @param end Last mesh to be processed
- */
- static void BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
- std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end);
-
- // -------------------------------------------------------------------
- /** Add a name prefix to all nodes in a scene.
- *
- * @param Current node. This function is called recursively.
- * @param prefix Prefix to be added to all nodes
- * @param len STring length
- */
- static void AddNodePrefixes(aiNode* node, const char* prefix,
- unsigned int len);
-
- // -------------------------------------------------------------------
- /** Add an offset to all mesh indices in a node graph
- *
- * @param Current node. This function is called recursively.
- * @param offset Offset to be added to all mesh indices
- */
- static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset);
-
- // -------------------------------------------------------------------
- /** Attach a list of node graphs to well-defined nodes in a master
- * graph. This is a helper for MergeScenes()
- *
- * @param master Master scene
- * @param srcList List of source scenes along with their attachment
- * points. If an attachment point is NULL (or does not exist in
- * the master graph), a scene is attached to the root of the master
- * graph (as an additional child node)
- * @duplicates List of duplicates. If elem[n] == n the scene is not
- * a duplicate. Otherwise elem[n] links scene n to its first occurence.
- */
- static void AttachToGraph ( aiScene* master,
- std::vector<NodeAttachmentInfo>& srcList);
-
- static void AttachToGraph (aiNode* attach,
- std::vector<NodeAttachmentInfo>& srcList);
-
-
- // -------------------------------------------------------------------
- /** Get a deep copy of a scene
- *
- * @param dest Receives a pointer to the destination scene
- * @param src Source scene - remains unmodified.
- */
- static void CopyScene(aiScene** dest,aiScene* source);
-
-
- // -------------------------------------------------------------------
- /** Get a flat copy of a scene
- *
- * Only the first hierarchy layer is copied. All pointer members of
- * aiScene are shared by source and destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param dest Receives a pointer to the destination scene
- * @param src Source scene - remains unmodified.
- */
- static void CopySceneFlat(aiScene** dest,aiScene* source);
-
-
- // -------------------------------------------------------------------
- /** Get a deep copy of a mesh
- *
- * @param dest Receives a pointer to the destination mesh
- * @param src Source mesh - remains unmodified.
- */
- static void Copy (aiMesh** dest, const aiMesh* src);
-
- // similar to Copy():
- static void Copy (aiMaterial** dest, const aiMaterial* src);
- static void Copy (aiTexture** dest, const aiTexture* src);
- static void Copy (aiAnimation** dest, const aiAnimation* src);
- static void Copy (aiCamera** dest, const aiCamera* src);
- static void Copy (aiBone** dest, const aiBone* src);
- static void Copy (aiLight** dest, const aiLight* src);
- static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
-
- // recursive, of course
- static void Copy (aiNode** dest, const aiNode* src);
-
-
-private:
-
- // -------------------------------------------------------------------
- // Same as AddNodePrefixes, but with an additional check
- static void AddNodePrefixesChecked(aiNode* node, const char* prefix,
- unsigned int len,
- std::vector<SceneHelper>& input,
- unsigned int cur);
-
- // -------------------------------------------------------------------
- // Add node identifiers to a hashing set
- static void AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes);
-
-
- // -------------------------------------------------------------------
- // Search for duplicate names
- static bool FindNameMatch(const aiString& name,
- std::vector<SceneHelper>& input, unsigned int cur);
-};
-
-}
-
-#endif // !! AI_SCENE_COMBINER_H_INC
diff --git a/3rdparty/assimp/code/ScenePreprocessor.cpp b/3rdparty/assimp/code/ScenePreprocessor.cpp
deleted file mode 100644
index 682a161a..00000000
--- a/3rdparty/assimp/code/ScenePreprocessor.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#include "ScenePreprocessor.h"
-
-using namespace Assimp;
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessScene ()
-{
- ai_assert(scene != NULL);
-
- // Process all meshes
- for (unsigned int i = 0; i < scene->mNumMeshes;++i)
- ProcessMesh(scene->mMeshes[i]);
-
- // - nothing to do for nodes for the moment
- // - nothing to do for textures for the moment
- // - nothing to do for lights for the moment
- // - nothing to do for cameras for the moment
-
- // Process all animations
- for (unsigned int i = 0; i < scene->mNumAnimations;++i)
- ProcessAnimation(scene->mAnimations[i]);
-
- // Generate a default material if none was specified
- if (!scene->mNumMaterials && scene->mNumMeshes) {
- scene->mMaterials = new aiMaterial*[2];
- MaterialHelper* helper;
-
- aiString name;
-
- // Check whether there are meshes with at least one set of uv coordinates ... add a dummy texture for them
- // meshes without texture coordinates receive a boring gray default material.
- unsigned int mat0 = 0xffffffff, mat1 = 0xffffffff;
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- if (scene->mMeshes[i]->mTextureCoords[0]) {
-
- if (mat0 == 0xffffffff) {
-
- scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
- name.Set("$texture.png");
- helper->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- name.Set(AI_DEFAULT_TEXTURED_MATERIAL_NAME);
- helper->AddProperty(&name,AI_MATKEY_NAME);
-
- mat0 = scene->mNumMaterials++;
- DefaultLogger::get()->debug("ScenePreprocessor: Adding textured material \'" AI_DEFAULT_TEXTURED_MATERIAL_NAME "\'");
- }
- scene->mMeshes[i]->mMaterialIndex = mat0;
- }
- else
- {
- if (mat1 == 0xffffffff) {
-
- scene->mMaterials[scene->mNumMaterials] = helper = new MaterialHelper();
- aiColor3D clr(0.6f,0.6f,0.6f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // setup the default name
- name.Set(AI_DEFAULT_MATERIAL_NAME);
- helper->AddProperty(&name,AI_MATKEY_NAME);
-
- mat1 = scene->mNumMaterials++;
- DefaultLogger::get()->debug("ScenePreprocessor: Adding grey material \'" AI_DEFAULT_MATERIAL_NAME "\'");
- }
- scene->mMeshes[i]->mMaterialIndex = mat1;
- }
- }
- }
-}
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
-{
- // If aiMesh::mNumUVComponents is *not* set assign the default value of 2
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- if (!mesh->mTextureCoords[i])
- mesh->mNumUVComponents[i] = 0;
-
- else {
- if ( !mesh->mNumUVComponents[i])
- mesh->mNumUVComponents[i] = 2;
-
- aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
-
- // Ensure unsued components are zeroed. This will make 1D texture channels work
- // as if they were 2D channels .. just in case an application doesn't handle
- // this case
- if (2 == mesh->mNumUVComponents[i]) {
- for (; p != end; ++p)
- p->z = 0.f;
- }
- else if (1 == mesh->mNumUVComponents[i]) {
- for (; p != end; ++p)
- p->z = p->y = 0.f;
- }
- else if (3 == mesh->mNumUVComponents[i]) {
-
- // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
- for (; p != end; ++p) {
- if (p->z != 0)
- break;
- }
- if (p == end) {
- DefaultLogger::get()->warn("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
- mesh->mNumUVComponents[i] = 2;
- }
- }
- }
- }
-
- // If the information which primitive types are there in the
- // mesh is currently not available, compute it.
- if (!mesh->mPrimitiveTypes) {
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
- aiFace& face = mesh->mFaces[a];
- switch (face.mNumIndices)
- {
- case 3u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
-
- case 2u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
-
- case 1u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
-
- default:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- }
- }
- }
-
- // If tangents and normals are given but no bitangents compute them
- if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
-
- mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
- for (unsigned int i = 0; i < mesh->mNumVertices;++i) {
- mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
- }
- }
-}
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
-{
- double first = 10e10, last = -10e10;
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* channel = anim->mChannels[i];
-
- /* If the exact duration of the animation is not given
- * compute it now.
- */
- if (anim->mDuration == -1.) {
-
- // Position keys
- for (unsigned int i = 0; i < channel->mNumPositionKeys;++i) {
- aiVectorKey& key = channel->mPositionKeys[i];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
-
- // Scaling keys
- for (unsigned int i = 0; i < channel->mNumScalingKeys;++i) {
- aiVectorKey& key = channel->mScalingKeys[i];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
-
- // Rotation keys
- for (unsigned int i = 0; i < channel->mNumRotationKeys;++i) {
- aiQuatKey& key = channel->mRotationKeys[i];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
- }
-
- /* Check whether the animation channel has no rotation
- * or position tracks. In this case we generate a dummy
- * track from the information we have in the transformation
- * matrix of the corresponding node.
- */
- if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys) {
- // Find the node that belongs to this animation
- aiNode* node = scene->mRootNode->FindNode(channel->mNodeName);
- if (node) // ValidateDS will complain later if 'node' is NULL
- {
- // Decompose the transformation matrix of the node
- aiVector3D scaling, position;
- aiQuaternion rotation;
-
- node->mTransformation.Decompose(scaling, rotation,position);
-
- // No rotation keys? Generate a dummy track
- if (!channel->mNumRotationKeys) {
- channel->mNumRotationKeys = 1;
- channel->mRotationKeys = new aiQuatKey[1];
- aiQuatKey& q = channel->mRotationKeys[0];
-
- q.mTime = 0.;
- q.mValue = rotation;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy rotation track has been generated");
- }
-
- // No scaling keys? Generate a dummy track
- if (!channel->mNumScalingKeys) {
- channel->mNumScalingKeys = 1;
- channel->mScalingKeys = new aiVectorKey[1];
- aiVectorKey& q = channel->mScalingKeys[0];
-
- q.mTime = 0.;
- q.mValue = scaling;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy scaling track has been generated");
- }
-
- // No position keys? Generate a dummy track
- if (!channel->mNumPositionKeys) {
- channel->mNumPositionKeys = 1;
- channel->mPositionKeys = new aiVectorKey[1];
- aiVectorKey& q = channel->mPositionKeys[0];
-
- q.mTime = 0.;
- q.mValue = position;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy position track has been generated");
- }
- }
- }
- }
-
- if (anim->mDuration == -1.) {
- DefaultLogger::get()->debug("ScenePreprocessor: Setting animation duration");
- anim->mDuration = last - std::min( first, 0. );
- }
-}
diff --git a/3rdparty/assimp/code/ScenePreprocessor.h b/3rdparty/assimp/code/ScenePreprocessor.h
deleted file mode 100644
index 01bbf7dc..00000000
--- a/3rdparty/assimp/code/ScenePreprocessor.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to search all meshes for
- degenerated faces */
-#ifndef AI_SCENE_PREPROCESSOR_H_INC
-#define AI_SCENE_PREPROCESSOR_H_INC
-
-class ScenePreprocessorTest;
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** ScenePreprocessor: Preprocess a scene before any post-processing
- * steps are executed.
- *
- * The step computes data that needn't necessarily be provided by the
- * importer, such as aiMesh::mPrimitiveTypes.
-*/
-// ----------------------------------------------------------------------------------
-class ASSIMP_API ScenePreprocessor
-{
- // Make ourselves a friend of the corresponding test unit.
- friend class ::ScenePreprocessorTest;
-public:
-
- // ----------------------------------------------------------------
- /** Default c'tpr. Use SetScene() to assign a scene to the object.
- */
- ScenePreprocessor()
- : scene (NULL)
- {}
-
- /** Constructs the object and assigns a specific scene to it
- */
- ScenePreprocessor(aiScene* _scene)
- : scene (_scene)
- {}
-
- // ----------------------------------------------------------------
- /** Assign a (new) scene to the object.
- *
- * One 'SceneProcessor' can be used for multiple scenes.
- * Call ProcessScene to have the scene preprocessed.
- * @param sc Scene to be processed.
- */
- void SetScene (aiScene* sc) {
- scene = sc;
- }
-
- // ----------------------------------------------------------------
- /** Preprocess the current scene
- */
- void ProcessScene ();
-
-protected:
-
- // ----------------------------------------------------------------
- /** Preprocess an animation in the scene
- * @param anim Anim to be preprocessed.
- */
- void ProcessAnimation (aiAnimation* anim);
-
-
- // ----------------------------------------------------------------
- /** Preprocess a mesh in the scene
- * @param mesh Mesh to be preprocessed.
- */
- void ProcessMesh (aiMesh* mesh);
-
-protected:
-
- //! Scene we're currently working on
- aiScene* scene;
-};
-
-
-} // ! end namespace Assimp
-
-#endif // include guard
diff --git a/3rdparty/assimp/code/SkeletonMeshBuilder.cpp b/3rdparty/assimp/code/SkeletonMeshBuilder.cpp
deleted file mode 100644
index 9e42270b..00000000
--- a/3rdparty/assimp/code/SkeletonMeshBuilder.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file SkeletonMeshBuilder.cpp
- * @brief Implementation of a little class to construct a dummy mesh for a skeleton
- */
-
-#include "AssimpPCH.h"
-#include "../include/aiScene.h"
-#include "SkeletonMeshBuilder.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// The constructor processes the given scene and adds a mesh there.
-SkeletonMeshBuilder::SkeletonMeshBuilder( aiScene* pScene, aiNode* root, bool bKnobsOnly)
-{
- // nothing to do if there's mesh data already present at the scene
- if ( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL)
- return;
-
- if (!root)
- root = pScene->mRootNode;
-
- mKnobsOnly = bKnobsOnly;
-
- // build some faces around each node
- CreateGeometry( root );
-
- // create a mesh to hold all the generated faces
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = CreateMesh();
- // and install it at the root node
- root->mNumMeshes = 1;
- root->mMeshes = new unsigned int[1];
- root->mMeshes[0] = 0;
-
- // create a dummy material for the mesh
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = CreateMaterial();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively builds a simple mesh representation for the given node
-void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode)
-{
- // add a joint entry for the node.
- const unsigned int vertexStartIndex = mVertices.size();
-
- // now build the geometry.
- if ( pNode->mNumChildren > 0 && !mKnobsOnly)
- {
- // If the node has children, we build little pointers to each of them
- for ( unsigned int a = 0; a < pNode->mNumChildren; a++)
- {
- // find a suitable coordinate system
- const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation;
- aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4);
- float distanceToChild = childpos.Length();
- if ( distanceToChild < 0.0001f)
- continue;
- aiVector3D up = aiVector3D( childpos).Normalize();
-
- aiVector3D orth( 1.0f, 0.0f, 0.0f);
- if ( fabs( orth * up) > 0.99f)
- orth.Set( 0.0f, 1.0f, 0.0f);
-
- aiVector3D front = (up ^ orth).Normalize();
- aiVector3D side = (front ^ up).Normalize();
-
- unsigned int localVertexStart = mVertices.size();
- mVertices.push_back( -front * distanceToChild * 0.1f);
- mVertices.push_back( childpos);
- mVertices.push_back( -side * distanceToChild * 0.1f);
- mVertices.push_back( -side * distanceToChild * 0.1f);
- mVertices.push_back( childpos);
- mVertices.push_back( front * distanceToChild * 0.1f);
- mVertices.push_back( front * distanceToChild * 0.1f);
- mVertices.push_back( childpos);
- mVertices.push_back( side * distanceToChild * 0.1f);
- mVertices.push_back( side * distanceToChild * 0.1f);
- mVertices.push_back( childpos);
- mVertices.push_back( -front * distanceToChild * 0.1f);
-
- mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2));
- mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5));
- mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8));
- mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11));
- }
- }
- else
- {
- // if the node has no children, it's an end node. Put a little knob there instead
- aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4);
- float sizeEstimate = ownpos.Length() * 0.18f;
-
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate));
-
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f));
- mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate));
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f));
-
- mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2));
- mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5));
- mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8));
- mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11));
- mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14));
- mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17));
- mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20));
- mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23));
- }
-
- unsigned int numVertices = mVertices.size() - vertexStartIndex;
- if ( numVertices > 0)
- {
- // create a bone affecting all the newly created vertices
- aiBone* bone = new aiBone;
- mBones.push_back( bone);
- bone->mName = pNode->mName;
-
- // calculate the bone offset matrix by concatenating the inverse transformations of all parents
- bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse();
- for ( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent)
- bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix;
-
- // add all the vertices to the bone's influences
- bone->mNumWeights = numVertices;
- bone->mWeights = new aiVertexWeight[numVertices];
- for ( unsigned int a = 0; a < numVertices; a++)
- bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0f);
-
- // HACK: (thom) transform all vertices to the bone's local space. Should be done before adding
- // them to the array, but I'm tired now and I'm annoyed.
- aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse();
- for ( unsigned int a = vertexStartIndex; a < mVertices.size(); a++)
- mVertices[a] = boneToMeshTransform * mVertices[a];
- }
-
- // and finally recurse into the children list
- for ( unsigned int a = 0; a < pNode->mNumChildren; a++)
- CreateGeometry( pNode->mChildren[a]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the mesh from the internally accumulated stuff and returns it.
-aiMesh* SkeletonMeshBuilder::CreateMesh()
-{
- aiMesh* mesh = new aiMesh();
-
- // add points
- mesh->mNumVertices = mVertices.size();
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices);
-
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- // add faces
- mesh->mNumFaces = mFaces.size();
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- for ( unsigned int a = 0; a < mesh->mNumFaces; a++)
- {
- const Face& inface = mFaces[a];
- aiFace& outface = mesh->mFaces[a];
- outface.mNumIndices = 3;
- outface.mIndices = new unsigned int[3];
- outface.mIndices[0] = inface.mIndices[0];
- outface.mIndices[1] = inface.mIndices[1];
- outface.mIndices[2] = inface.mIndices[2];
-
- // Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize
- // the skeleton, so it's good if there's a visual difference to the rest of the geometry
- aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^
- (mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]]));
-
- if (nor.Length() < 1e-5f) /* ensure that FindInvalidData won't remove us ...*/
- nor = aiVector3D(1.f,0.f,0.f);
-
- for (unsigned int n = 0; n < 3; ++n)
- mesh->mNormals[inface.mIndices[n]] = nor;
- }
-
- // add the bones
- mesh->mNumBones = mBones.size();
- mesh->mBones = new aiBone*[mesh->mNumBones];
- std::copy( mBones.begin(), mBones.end(), mesh->mBones);
-
- // default
- mesh->mMaterialIndex = 0;
-
- return mesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates a dummy material and returns it.
-aiMaterial* SkeletonMeshBuilder::CreateMaterial()
-{
- Assimp::MaterialHelper* matHelper = new Assimp::MaterialHelper;
-
- // Name
- aiString matName( std::string( "SkeletonMaterial"));
- matHelper->AddProperty( &matName, AI_MATKEY_NAME);
-
- // Prevent backface culling
- const int no_cull = 1;
- matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED);
-
- return matHelper;
-}
diff --git a/3rdparty/assimp/code/SkeletonMeshBuilder.h b/3rdparty/assimp/code/SkeletonMeshBuilder.h
deleted file mode 100644
index 3989e7cf..00000000
--- a/3rdparty/assimp/code/SkeletonMeshBuilder.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/** Helper class to construct a dummy mesh for file formats containing only motion data */
-
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file SkeletonMeshBuilder.h
- * Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes
- * for animation skeletons.
- */
-
-#ifndef AI_SKELETONMESHBUILDER_H_INC
-#define AI_SKELETONMESHBUILDER_H_INC
-
-#include <vector>
-#include "../include/aiMesh.h"
-
-struct aiScene;
-struct aiNode;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/**
- * This little helper class constructs a dummy mesh for a given scene
- * the resembles the node hierarchy. This is useful for file formats
- * that don't carry any mesh data but only animation data.
- */
-class ASSIMP_API SkeletonMeshBuilder
-{
-public:
-
- // -------------------------------------------------------------------
- /** The constructor processes the given scene and adds a mesh there.
- *
- * Does nothing if the scene already has mesh data.
- * @param pScene The scene for which a skeleton mesh should be constructed.
- * @param root The node to start with. NULL is the scene root
- * @param bKnobsOnly Set this to true if you don't want the connectors
- * between the knobs representing the nodes.
- */
- SkeletonMeshBuilder( aiScene* pScene, aiNode* root = NULL,
- bool bKnobsOnly = false);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Recursively builds a simple mesh representation for the given node
- * and also creates a joint for the node that affects this part of
- * the mesh.
- * @param pNode The node to build geometry for.
- */
- void CreateGeometry( const aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** Creates the mesh from the internally accumulated stuff and returns it.
- */
- aiMesh* CreateMesh();
-
- // -------------------------------------------------------------------
- /** Creates a dummy material and returns it. */
- aiMaterial* CreateMaterial();
-
-protected:
- /** space to assemble the mesh data: points */
- std::vector<aiVector3D> mVertices;
-
- /** faces */
- struct Face
- {
- unsigned int mIndices[3];
- Face();
- Face( unsigned int p0, unsigned int p1, unsigned int p2)
- { mIndices[0] = p0; mIndices[1] = p1; mIndices[2] = p2; }
- };
- std::vector<Face> mFaces;
-
- /** bones */
- std::vector<aiBone*> mBones;
-
- bool mKnobsOnly;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SKELETONMESHBUILDER_H_INC
diff --git a/3rdparty/assimp/code/SmoothingGroups.h b/3rdparty/assimp/code/SmoothingGroups.h
deleted file mode 100644
index 50535820..00000000
--- a/3rdparty/assimp/code/SmoothingGroups.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines the helper data structures for importing 3DS files.
-http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
-
-#ifndef AI_SMOOTHINGGROUPS_H_INC
-#define AI_SMOOTHINGGROUPS_H_INC
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a face with smoothing groups assigned */
-struct FaceWithSmoothingGroup
-{
- FaceWithSmoothingGroup() : iSmoothGroup(0)
- {
- // let the rest uninitialized for performance - in release builds.
- // in debug builds set all indices to a common magic value
-#ifdef _DEBUG
- this->mIndices[0] = 0xffffffff;
- this->mIndices[1] = 0xffffffff;
- this->mIndices[2] = 0xffffffff;
-#endif
- }
-
-
- //! Indices. .3ds is using uint16. However, after
- //! an unique vrtex set has been generated it might
- //! be an index becomes > 2^16
- uint32_t mIndices[3];
-
- //! specifies to which smoothing group the face belongs to
- uint32_t iSmoothGroup;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a mesh whose faces have smoothing
- groups assigned. This allows us to reuse the code for normal computations
- from smoothings groups for several loaders (3DS, ASE). All of them
- use face structures which inherit from #FaceWithSmoothingGroup,
- but as they add extra members and need to be copied by value we
- need to use a template here.
- */
-template <class T>
-struct MeshWithSmoothingGroups
-{
- //! Vertex positions
- std::vector<aiVector3D> mPositions;
-
- //! Face lists
- std::vector<T> mFaces;
-
- //! List of normal vectors
- std::vector<aiVector3D> mNormals;
-};
-
-// ---------------------------------------------------------------------------
-/** Computes normal vectors for the mesh
- */
-template <class T>
-void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh);
-
-
-// include implementations
-#include "SmoothingGroups.inl"
-
-#endif // !! AI_SMOOTHINGGROUPS_H_INC
diff --git a/3rdparty/assimp/code/SmoothingGroups.inl b/3rdparty/assimp/code/SmoothingGroups.inl
deleted file mode 100644
index 10eb7d25..00000000
--- a/3rdparty/assimp/code/SmoothingGroups.inl
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Generation of normal vectors basing on smoothing groups */
-
-#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
-#define AI_SMOOTHINGGROUPS_INL_INCLUDED
-
-// internal headers
-#include "SGSpatialSort.h"
-
-// CRT header
-#include <algorithm>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
-{
- // First generate face normals
- sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D());
- for ( unsigned int a = 0; a < sMesh.mFaces.size(); a++)
- {
- T& face = sMesh.mFaces[a];
-
- aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
- aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
- aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
-
- aiVector3D pDelta1 = *pV2 - *pV1;
- aiVector3D pDelta2 = *pV3 - *pV1;
- aiVector3D vNor = pDelta1 ^ pDelta2;
-
- for (unsigned int c = 0; c < 3;++c)
- sMesh.mNormals[face.mIndices[c]] = vNor;
- }
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
- for ( unsigned int a = 0; a < sMesh.mPositions.size(); a++)
- {
- minVec.x = std::min( minVec.x, sMesh.mPositions[a].x);
- minVec.y = std::min( minVec.y, sMesh.mPositions[a].y);
- minVec.z = std::min( minVec.z, sMesh.mPositions[a].z);
- maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x);
- maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y);
- maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z);
- }
- const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
- std::vector<aiVector3D> avNormals;
- avNormals.resize(sMesh.mNormals.size());
-
- // now generate the spatial sort tree
- SGSpatialSort sSort;
- for ( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
- i != sMesh.mFaces.end();++i)
- {
- for (unsigned int c = 0; c < 3;++c)
- sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup);
- }
- sSort.Prepare();
-
- std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
- for ( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
- i != sMesh.mFaces.end();++i)
- {
- std::vector<unsigned int> poResult;
- for (unsigned int c = 0; c < 3;++c)
- {
- register unsigned int idx = (*i).mIndices[c];
- if (vertexDone[idx])continue;
-
- sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup,
- posEpsilon,poResult);
-
- aiVector3D vNormals;
- for (std::vector<unsigned int>::const_iterator
- a = poResult.begin();
- a != poResult.end();++a)
- {
- vNormals += sMesh.mNormals[(*a)];
- }
- vNormals.Normalize();
-
- // write back into all affected normals
- for (std::vector<unsigned int>::const_iterator
- a = poResult.begin();
- a != poResult.end();++a)
- {
- idx = *a;
- avNormals [idx] = vNormals;
- vertexDone[idx] = true;
- }
- }
- }
- sMesh.mNormals = avNormals;
-}
-
-#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED
diff --git a/3rdparty/assimp/code/SortByPTypeProcess.cpp b/3rdparty/assimp/code/SortByPTypeProcess.cpp
deleted file mode 100644
index 18cd1f87..00000000
--- a/3rdparty/assimp/code/SortByPTypeProcess.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the DeterminePTypeHelperProcess and
- * SortByPTypeProcess post-process steps.
-*/
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "ProcessHelper.h"
-#include "SortByPTypeProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-SortByPTypeProcess::SortByPTypeProcess()
-{
- configRemoveMeshes = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SortByPTypeProcess::~SortByPTypeProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SortByPType) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void SortByPTypeProcess::SetupProperties(const Importer* pImp)
-{
- configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update changed meshes in all nodes
-void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
-{
-// std::vector<unsigned int>::const_iterator it;
-
- if (node->mNumMeshes)
- {
- unsigned int newSize = 0;
- for (unsigned int m = 0; m< node->mNumMeshes; ++m)
- {
- unsigned int add = node->mMeshes[m]<<2;
- for (unsigned int i = 0; i < 4;++i)
- {
- if (0xffffffff != replaceMeshIndex[add+i])++newSize;
- }
- }
- if (!newSize)
- {
- delete[] node->mMeshes;
- node->mNumMeshes = 0;
- node->mMeshes = NULL;
- }
- else
- {
- // Try to reuse the old array if possible
- unsigned int* newMeshes = (newSize > node->mNumMeshes
- ? new unsigned int[newSize] : node->mMeshes);
-
- for (unsigned int m = 0; m< node->mNumMeshes; ++m)
- {
- unsigned int add = node->mMeshes[m]<<2;
- for (unsigned int i = 0; i < 4;++i)
- {
- if (0xffffffff != replaceMeshIndex[add+i])
- *newMeshes++ = replaceMeshIndex[add+i];
- }
- }
- if (newSize > node->mNumMeshes)
- delete[] node->mMeshes;
-
- node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
- }
- }
-
- // call all subnodes recursively
- for (unsigned int m = 0; m < node->mNumChildren; ++m)
- UpdateNodes(replaceMeshIndex,node->mChildren[m]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SortByPTypeProcess::Execute( aiScene* pScene)
-{
- if (!pScene->mNumMeshes)
- {
- DefaultLogger::get()->debug("SortByPTypeProcess skipped, there are no meshes");
- return;
- }
-
- DefaultLogger::get()->debug("SortByPTypeProcess begin");
-
- unsigned int aiNumMeshesPerPType[4] = {0,0,0,0};
-
- std::vector<aiMesh*> outMeshes;
- outMeshes.reserve(pScene->mNumMeshes<<1u);
-
- bool bAnyChanges = false;
-
- std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,0xffffffff);
- std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiMesh* mesh = pScene->mMeshes[i];
- ai_assert(0 != mesh->mPrimitiveTypes);
-
- // if there's just one primitive type in the mesh there's nothing to do for us
- unsigned int num = 0;
- if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT)
- {
- ++aiNumMeshesPerPType[0];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE)
- {
- ++aiNumMeshesPerPType[1];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)
- {
- ++aiNumMeshesPerPType[2];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)
- {
- ++aiNumMeshesPerPType[3];
- ++num;
- }
-
- if (1 == num)
- {
- if (!(configRemoveMeshes & mesh->mPrimitiveTypes))
- {
- *meshIdx = (unsigned int) outMeshes.size();
- outMeshes.push_back(mesh);
- }
- else bAnyChanges = true;
-
- meshIdx += 4;
- continue;
- }
- bAnyChanges = true;
-
- // reuse our current mesh arrays for the submesh
- // with the largest numer of primitives
- unsigned int aiNumPerPType[4] = {0,0,0,0};
- aiFace* pFirstFace = mesh->mFaces;
- aiFace* const pLastFace = pFirstFace + mesh->mNumFaces;
-
- unsigned int numPolyVerts = 0;
- for (;pFirstFace != pLastFace; ++pFirstFace)
- {
- if (pFirstFace->mNumIndices <= 3)
- ++aiNumPerPType[pFirstFace->mNumIndices-1];
- else
- {
- ++aiNumPerPType[3];
- numPolyVerts += pFirstFace-> mNumIndices;
- }
- }
-
- VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
- for (unsigned int real = 0; real < 4; ++real,++meshIdx)
- {
- if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
- {
- continue;
- }
-
- *meshIdx = (unsigned int) outMeshes.size();
- outMeshes.push_back(new aiMesh());
- aiMesh* out = outMeshes.back();
-
- // the name carries the adjacency information between the meshes
- out->mName = mesh->mName;
-
- // copy data members
- out->mPrimitiveTypes = 1u << real;
- out->mMaterialIndex = mesh->mMaterialIndex;
-
- // allocate output storage
- out->mNumFaces = aiNumPerPType[real];
- aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces];
-
- out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));
-
- aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
- aiVector3D *uv [AI_MAX_NUMBER_OF_TEXTURECOORDS];
- aiColor4D *cols [AI_MAX_NUMBER_OF_COLOR_SETS];
-
- if (mesh->mVertices)
- vert = out->mVertices = new aiVector3D[out->mNumVertices];
-
- if (mesh->mNormals)
- nor = out->mNormals = new aiVector3D[out->mNumVertices];
-
- if (mesh->mTangents)
- {
- tan = out->mTangents = new aiVector3D[out->mNumVertices];
- bit = out->mBitangents = new aiVector3D[out->mNumVertices];
- }
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- if (mesh->mTextureCoords[i])
- uv[i] = out->mTextureCoords[i] = new aiVector3D[out->mNumVertices];
- else uv[i] = NULL;
-
- out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
- }
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- {
- if (mesh->mColors[i])
- cols[i] = out->mColors[i] = new aiColor4D[out->mNumVertices];
- else cols[i] = NULL;
- }
-
- typedef std::vector< aiVertexWeight > TempBoneInfo;
- std::vector< TempBoneInfo > tempBones(mesh->mNumBones);
-
- // try to guess how much storage we'll need
- for (unsigned int q = 0; q < mesh->mNumBones;++q)
- {
- tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1));
- }
-
- unsigned int outIdx = 0;
- for (unsigned int m = 0; m < mesh->mNumFaces; ++m)
- {
- aiFace& in = mesh->mFaces[m];
- if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1))
- {
- continue;
- }
-
- outFaces->mNumIndices = in.mNumIndices;
- outFaces->mIndices = in.mIndices;
-
- for (unsigned int q = 0; q < in.mNumIndices; ++q)
- {
- register unsigned int idx = in.mIndices[q];
-
- // process all bones of this index
- if (avw)
- {
- VertexWeightTable& tbl = avw[idx];
- for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
- it != end; ++it)
- {
- tempBones[ (*it).first ].push_back( aiVertexWeight(outIdx, (*it).second) );
- }
- }
-
- if (vert)
- {
- *vert++ = mesh->mVertices[idx];
- //mesh->mVertices[idx].x = get_qnan();
- }
- if (nor )*nor++ = mesh->mNormals[idx];
- if (tan )
- {
- *tan++ = mesh->mTangents[idx];
- *bit++ = mesh->mBitangents[idx];
- }
-
- for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp)
- {
- if (!uv[pp])break;
- *uv[pp]++ = mesh->mTextureCoords[pp][idx];
- }
-
- for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp)
- {
- if (!cols[pp])break;
- *cols[pp]++ = mesh->mColors[pp][idx];
- }
-
- in.mIndices[q] = outIdx++;
- }
-
- in.mIndices = NULL;
- ++outFaces;
- }
- ai_assert(outFaces == out->mFaces + out->mNumFaces);
-
- // now generate output bones
- for (unsigned int q = 0; q < mesh->mNumBones;++q)
- if (!tempBones[q].empty())++out->mNumBones;
-
- if (out->mNumBones)
- {
- out->mBones = new aiBone*[out->mNumBones];
- for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q)
- {
- TempBoneInfo& in = tempBones[q];
- if (in.empty())continue;
-
- aiBone* srcBone = mesh->mBones[q];
- aiBone* bone = out->mBones[real] = new aiBone();
-
- bone->mName = srcBone->mName;
- bone->mOffsetMatrix = srcBone->mOffsetMatrix;
-
- bone->mNumWeights = (unsigned int)in.size();
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
-
- ::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(aiVertexWeight));
-
- ++real;
- }
- }
- }
-
- // delete the per-vertex bone weights table
- delete[] avw;
-
- // delete the input mesh
- delete mesh;
- }
-
- if (outMeshes.empty())
- {
- // This should not occur
- throw DeadlyImportError("No meshes remaining");
- }
-
- // If we added at least one mesh process all nodes in the node
- // graph and update their respective mesh indices.
- if (bAnyChanges)
- {
- UpdateNodes(replaceMeshIndex,pScene->mRootNode);
- }
-
- if (outMeshes.size() != pScene->mNumMeshes)
- {
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)outMeshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- }
- ::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
-
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[1024];
- ::sprintf(buffer,"Points: %i%s, Lines: %i%s, Triangles: %i%s, Polygons: %i%s (Meshes, X = removed)",
- aiNumMeshesPerPType[0], (configRemoveMeshes & aiPrimitiveType_POINT ? "X" : ""),
- aiNumMeshesPerPType[1], (configRemoveMeshes & aiPrimitiveType_LINE ? "X" : ""),
- aiNumMeshesPerPType[2], (configRemoveMeshes & aiPrimitiveType_TRIANGLE ? "X" : ""),
- aiNumMeshesPerPType[3], (configRemoveMeshes & aiPrimitiveType_POLYGON ? "X" : ""));
- DefaultLogger::get()->info(buffer);
- DefaultLogger::get()->debug("SortByPTypeProcess finished");
- }
-}
-
diff --git a/3rdparty/assimp/code/SortByPTypeProcess.h b/3rdparty/assimp/code/SortByPTypeProcess.h
deleted file mode 100644
index 835dedc8..00000000
--- a/3rdparty/assimp/code/SortByPTypeProcess.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to sort meshes by the types
- of primitives they contain */
-#ifndef AI_SORTBYPTYPEPROCESS_H_INC
-#define AI_SORTBYPTYPEPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiMesh.h"
-
-class SortByPTypeProcessTest;
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
- * A mesh with 5 lines, 3 points and 145 triangles would be split in 3
- * submeshes.
-*/
-class ASSIMP_API SortByPTypeProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::SortByPTypeProcessTest; // grant the unit test full access to us
-
-protected:
- /** Constructor to be privately used by Importer */
- SortByPTypeProcess();
-
- /** Destructor, private as well */
- ~SortByPTypeProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-private:
-
- int configRemoveMeshes;
-};
-
-
-} // end of namespace Assimp
-
-#endif // !!AI_SORTBYPTYPEPROCESS_H_INC
diff --git a/3rdparty/assimp/code/SpatialSort.cpp b/3rdparty/assimp/code/SpatialSort.cpp
deleted file mode 100644
index c39426db..00000000
--- a/3rdparty/assimp/code/SpatialSort.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the helper class to quickly find vertices close to a given position */
-
-#include "AssimpPCH.h"
-#include "SpatialSort.h"
-
-using namespace Assimp;
-
-// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8.
-#ifndef CHAR_BIT
-# define CHAR_BIT 8
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Constructs a spatially sorted representation from the given position array.
-SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset)
-
- // define the reference plane. We choose some arbitrary vector away from all basic axises
- // in the hope that no model spreads all its vertices along this plane.
- : mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
-{
- mPlaneNormal.Normalize();
- Fill(pPositions,pNumPositions,pElementOffset);
-}
-
-// ------------------------------------------------------------------------------------------------
-SpatialSort :: SpatialSort()
-: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
-{
- mPlaneNormal.Normalize();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SpatialSort::~SpatialSort()
-{
- // nothing to do here, everything destructs automatically
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize /*= true */)
-{
- mPositions.clear();
- Append(pPositions,pNumPositions,pElementOffset,pFinalize);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort :: Finalize()
-{
- std::sort( mPositions.begin(), mPositions.end());
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize /*= true */)
-{
- // store references to all given positions along with their distance to the reference plane
- const size_t initial = mPositions.size();
- mPositions.reserve(initial + (pFinalize?pNumPositions:pNumPositions*2));
- for ( unsigned int a = 0; a < pNumPositions; a++)
- {
- const char* tempPointer = reinterpret_cast<const char*> (pPositions);
- const aiVector3D* vec = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset);
-
- // store position by index and distance
- float distance = *vec * mPlaneNormal;
- mPositions.push_back( Entry( a+initial, *vec, distance));
- }
-
- if (pFinalize) {
- // now sort the array ascending by distance.
- Finalize();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns an iterator for all positions close to the given position.
-void SpatialSort::FindPositions( const aiVector3D& pPosition,
- float pRadius, std::vector<unsigned int>& poResults) const
-{
- const float dist = pPosition * mPlaneNormal;
- const float minDist = dist - pRadius, maxDist = dist + pRadius;
-
- // clear the array in this strange fashion because a simple clear() would also deallocate
- // the array which we want to avoid
- poResults.erase( poResults.begin(), poResults.end());
-
- // quick check for positions outside the range
- if ( mPositions.size() == 0)
- return;
- if ( maxDist < mPositions.front().mDistance)
- return;
- if ( minDist > mPositions.back().mDistance)
- return;
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while ( binaryStepSize > 1)
- {
- if ( mPositions[index].mDistance < minDist)
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while ( index > 0 && mPositions[index].mDistance > minDist)
- index--;
- while ( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
- index++;
-
- // Mow start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the given radius to the result aray
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- const float pSquared = pRadius*pRadius;
- while ( it->mDistance < maxDist)
- {
- if ( (it->mPosition - pPosition).SquareLength() < pSquared)
- poResults.push_back( it->mIndex);
- ++it;
- if ( it == mPositions.end())
- break;
- }
-
- // that's it
-}
-
-namespace {
-
- // Binary, signed-integer representation of a single-precision floating-point value.
- // IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are
- // ordered the same way when their bits are reinterpreted as sign-magnitude integers."
- // This allows us to convert all floating-point numbers to signed integers of arbitrary size
- // and then use them to work with ULPs (Units in the Last Place, for high-precision
- // computations) or to compare them (integer comparisons are faster than floating-point
- // comparisons on many platforms).
- typedef signed int BinFloat;
-
- // --------------------------------------------------------------------------------------------
- // Converts the bit pattern of a floating-point number to its signed integer representation.
- BinFloat ToBinary( const float & pValue) {
-
- // If this assertion fails, signed int is not big enough to store a float on your platform.
- // Please correct the declaration of BinFloat a few lines above - but do it in a portable,
- // #ifdef'd manner!
- BOOST_STATIC_ASSERT( sizeof(BinFloat) >= sizeof(float));
-
- #if defined( _MSC_VER)
- // If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
- // code has just become legacy code! Find out the current value of _MSC_VER and modify
- // the #if above so it evaluates false on the current and all upcoming VC versions (or
- // on the current platform, if LP64 or LLP64 are still used on other platforms).
- BOOST_STATIC_ASSERT( sizeof(BinFloat) == sizeof(float));
-
- // This works best on Visual C++, but other compilers have their problems with it.
- const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
- #else
- // On many compilers, reinterpreting a float address as an integer causes aliasing
- // problems. This is an ugly but more or less safe way of doing it.
- union {
- float asFloat;
- BinFloat asBin;
- } conversion;
- conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
- conversion.asFloat = pValue;
- const BinFloat binValue = conversion.asBin;
- #endif
-
- // floating-point numbers are of sign-magnitude format, so find out what signed number
- // representation we must convert negative values to.
- // See http://en.wikipedia.org/wiki/Signed_number_representations.
-
- // Two's complement?
- if ( (-42 == (~42 + 1)) && (binValue & 0x80000000))
- return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
- // One's complement?
- else if ( (-42 == ~42) && (binValue & 0x80000000))
- return BinFloat(-0) - binValue;
- // Sign-magnitude?
- else if ( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
- return binValue;
- else
- return binValue;
- }
-
-} // namespace
-
-// ------------------------------------------------------------------------------------------------
-// Fills an array with indices of all positions indentical to the given position. In opposite to
-// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
-void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
- std::vector<unsigned int>& poResults) const
-{
- // Epsilons have a huge disadvantage: they are of constant precision, while floating-point
- // values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
- // if you apply it to 0.001, it is enormous.
-
- // The best way to overcome this is the unit in the last place (ULP). A precision of 2 ULPs
- // tells us that a float does not differ more than 2 bits from the "real" value. ULPs are of
- // logarithmic precision - around 1, they are 1(2^24) and around 10000, they are 0.00125.
-
- // For standard C math, we can assume a precision of 0.5 ULPs according to IEEE 754. The
- // incoming vertex positions might have already been transformed, probably using rather
- // inaccurate SSE instructions, so we assume a tolerance of 4 ULPs to safely identify
- // identical vertex positions.
- static const int toleranceInULPs = 4;
- // An interesting point is that the inaccuracy grows linear with the number of operations:
- // multiplying to numbers, each inaccurate to four ULPs, results in an inaccuracy of four ULPs
- // plus 0.5 ULPs for the multiplication.
- // To compute the distance to the plane, a dot product is needed - that is a multiplication and
- // an addition on each number.
- static const int distanceToleranceInULPs = toleranceInULPs + 1;
- // The squared distance between two 3D vectors is computed the same way, but with an additional
- // subtraction.
- static const int distance3DToleranceInULPs = distanceToleranceInULPs + 1;
-
- // Convert the plane distance to its signed integer representation so the ULPs tolerance can be
- // applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
- const BinFloat minDistBinary = ToBinary( pPosition * mPlaneNormal) - distanceToleranceInULPs;
- const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
-
- // clear the array in this strange fashion because a simple clear() would also deallocate
- // the array which we want to avoid
- poResults.erase( poResults.begin(), poResults.end());
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while ( binaryStepSize > 1)
- {
- // Ugly, but conditional jumps are faster with integers than with floats
- if ( minDistBinary > ToBinary(mPositions[index].mDistance))
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while ( index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance) )
- index--;
- while ( index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance))
- index++;
-
- // Now start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the tolerance to the result aray
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- while ( ToBinary(it->mDistance) < maxDistBinary)
- {
- if ( distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength()))
- poResults.push_back(it->mIndex);
- ++it;
- if ( it == mPositions.end())
- break;
- }
-
- // that's it
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,float pRadius) const
-{
- fill.resize(mPositions.size(),0xffffffff);
- float dist, maxDist;
-
- unsigned int t=0;
- const float pSquared = pRadius*pRadius;
- for (size_t i = 0; i < mPositions.size();) {
- dist = mPositions[i].mPosition * mPlaneNormal;
- maxDist = dist + pRadius;
-
- fill[mPositions[i].mIndex] = t;
- const aiVector3D& oldpos = mPositions[i].mPosition;
- for (++i; i < fill.size() && mPositions[i].mDistance < maxDist
- && (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i)
- {
- fill[mPositions[i].mIndex] = t;
- }
- ++t;
- }
-
-#ifdef _DEBUG
-
- // debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1
- for (size_t i = 0; i < fill.size(); ++i) {
- ai_assert(fill[i]<mPositions.size());
- }
-
-#endif
- return t;
-}
-
diff --git a/3rdparty/assimp/code/SpatialSort.h b/3rdparty/assimp/code/SpatialSort.h
deleted file mode 100644
index 032b30d8..00000000
--- a/3rdparty/assimp/code/SpatialSort.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** Small helper classes to optimise finding vertizes close to a given location */
-#ifndef AI_SPATIALSORT_H_INC
-#define AI_SPATIALSORT_H_INC
-
-#include <vector>
-#include "../include/aiTypes.h"
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-/** A little helper class to quickly find all vertices in the epsilon environment of a given
- * position. Construct an instance with an array of positions. The class stores the given positions
- * by their indices and sorts them by their distance to an arbitrary chosen plane.
- * You can then query the instance for all vertices close to a given position in an average O(log n)
- * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen
- * so that it avoids common planes in usual data sets. */
-// ------------------------------------------------------------------------------------------------
-class ASSIMP_API SpatialSort
-{
-public:
-
- SpatialSort();
-
- // ------------------------------------------------------------------------------------
- /** Constructs a spatially sorted representation from the given position array.
- * Supply the positions in its layout in memory, the class will only refer to them
- * by index.
- * @param pPositions Pointer to the first position vector of the array.
- * @param pNumPositions Number of vectors to expect in that array.
- * @param pElementOffset Offset in bytes from the beginning of one vector in memory
- * to the beginning of the next vector. */
- SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset);
-
- /** Destructor */
- ~SpatialSort();
-
-public:
-
- // ------------------------------------------------------------------------------------
- /** Sets the input data for the SpatialSort. This replaces existing data, if any.
- * The new data receives new indices in ascending order.
- *
- * @param pPositions Pointer to the first position vector of the array.
- * @param pNumPositions Number of vectors to expect in that array.
- * @param pElementOffset Offset in bytes from the beginning of one vector in memory
- * to the beginning of the next vector.
- * @param pFinalize Specifies whether the SpatialSort's internal representation
- * is finalized after the new data has been added. Finalization is
- * required in order to use #FindPosition() or #GenerateMappingTable().
- * If you don't finalize yet, you can use #Append() to add data from
- * other sources.*/
- void Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize = true);
-
-
- // ------------------------------------------------------------------------------------
- /** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */
- void Append( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize = true);
-
-
- // ------------------------------------------------------------------------------------
- /** Finalize the spatial hash data structure. This can be useful after
- * multiple calls to #Append() with the pFinalize parameter set to false.
- * This is finally required before one of #FindPositions() and #GenerateMappingTable()
- * can be called to query the spatial sort.*/
- void Finalize();
-
- // ------------------------------------------------------------------------------------
- /** Returns an iterator for all positions close to the given position.
- * @param pPosition The position to look for vertices.
- * @param pRadius Maximal distance from the position a vertex may have to be counted in.
- * @param poResults The container to store the indices of the found positions.
- * Will be emptied by the call so it may contain anything.
- * @return An iterator to iterate over all vertices in the given area.*/
- void FindPositions( const aiVector3D& pPosition, float pRadius,
- std::vector<unsigned int>& poResults) const;
-
- // ------------------------------------------------------------------------------------
- /** Fills an array with indices of all positions indentical to the given position. In
- * opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of
- * four floating-point units.
- * @param pPosition The position to look for vertices.
- * @param poResults The container to store the indices of the found positions.
- * Will be emptied by the call so it may contain anything.*/
- void FindIdenticalPositions( const aiVector3D& pPosition,
- std::vector<unsigned int>& poResults) const;
-
- // ------------------------------------------------------------------------------------
- /** Compute a table that maps each vertex ID referring to a spatially close
- * enough position to the same output ID. Output IDs are assigned in ascending order
- * from 0...n.
- * @param fill Will be filled with numPositions entries.
- * @param pRadius Maximal distance from the position a vertex may have to
- * be counted in.
- * @return Number of unique vertices (n). */
- unsigned int GenerateMappingTable(std::vector<unsigned int>& fill,
- float pRadius) const;
-
-protected:
- /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
- aiVector3D mPlaneNormal;
-
- /** An entry in a spatially sorted position array. Consists of a vertex index,
- * its position and its precalculated distance from the reference plane */
- struct Entry
- {
- unsigned int mIndex; ///< The vertex referred by this entry
- aiVector3D mPosition; ///< Position
- float mDistance; ///< Distance of this vertex to the sorting plane
-
- Entry() { /** intentionally not initialized.*/ }
- Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance)
- : mIndex( pIndex), mPosition( pPosition), mDistance( pDistance)
- { }
-
- bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
- };
-
- // all positions, sorted by distance to the sorting plane
- std::vector<Entry> mPositions;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SPATIALSORT_H_INC
diff --git a/3rdparty/assimp/code/SplitLargeMeshes.cpp b/3rdparty/assimp/code/SplitLargeMeshes.cpp
deleted file mode 100644
index f729d469..00000000
--- a/3rdparty/assimp/code/SplitLargeMeshes.cpp
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Implementation of the SplitLargeMeshes postprocessing step
-*/
-
-#include "AssimpPCH.h"
-
-// internal headers of the post-processing framework
-#include "SplitLargeMeshes.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle()
-{
- LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SplitLargeMeshes) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
-{
- if (0xffffffff == this->LIMIT)return;
-
- DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle begin");
- std::vector<std::pair<aiMesh*, unsigned int> > avList;
-
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- this->SplitMesh(a, pScene->mMeshes[a],avList);
-
- if (avList.size() != pScene->mNumMeshes)
- {
- // it seems something has been splitted. rebuild the mesh list
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)avList.size();
- pScene->mMeshes = new aiMesh*[avList.size()];
-
- for (unsigned int i = 0; i < avList.size();++i)
- pScene->mMeshes[i] = avList[i].first;
-
- // now we need to update all nodes
- this->UpdateNode(pScene->mRootNode,avList);
- DefaultLogger::get()->info("SplitLargeMeshesProcess_Triangle finished. Meshes have been splitted");
- }
- else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp)
-{
- // get the current value of the split property
- this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update a node after some meshes have been split
-void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
- const std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- // for every index in out list build a new entry
- std::vector<unsigned int> aiEntries;
- aiEntries.reserve(pcNode->mNumMeshes + 1);
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- for (unsigned int a = 0; a < avList.size();++a)
- {
- if (avList[a].second == pcNode->mMeshes[i])
- {
- aiEntries.push_back(a);
- }
- }
- }
-
- // now build the new list
- delete pcNode->mMeshes;
- pcNode->mNumMeshes = (unsigned int)aiEntries.size();
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
-
- for (unsigned int b = 0; b < pcNode->mNumMeshes;++b)
- pcNode->mMeshes[b] = aiEntries[b];
-
- // recusively update all other nodes
- for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
- {
- UpdateNode ( pcNode->mChildren[i], avList );
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Triangle::SplitMesh(
- unsigned int a,
- aiMesh* pMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
- {
- DefaultLogger::get()->info("Mesh exceeds the triangle limit. It will be split ...");
-
- // we need to split this mesh into sub meshes
- // determine the size of a submesh
- const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;
-
- const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
- const unsigned int iOutVertexNum = iOutFaceNum * 3;
-
- // now generate all submeshes
- for (unsigned int i = 0; i < iSubMeshes;++i)
- {
- aiMesh* pcMesh = new aiMesh;
- pcMesh->mNumFaces = iOutFaceNum;
- pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
-
- // the name carries the adjacency information between the meshes
- pcMesh->mName = pMesh->mName;
-
- if (i == iSubMeshes-1)
- {
- pcMesh->mNumFaces = iOutFaceNum + (
- pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
- }
- // copy the list of faces
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- const unsigned int iBase = iOutFaceNum * i;
-
- // get the total number of indices
- unsigned int iCnt = 0;
- for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p)
- {
- iCnt += pMesh->mFaces[p].mNumIndices;
- }
- pcMesh->mNumVertices = iCnt;
-
- // allocate storage
- if (pMesh->mVertices != NULL)
- pcMesh->mVertices = new aiVector3D[iCnt];
-
- if (pMesh->HasNormals())
- pcMesh->mNormals = new aiVector3D[iCnt];
-
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents = new aiVector3D[iCnt];
- pcMesh->mBitangents = new aiVector3D[iCnt];
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
- if (pMesh->HasTextureCoords( c))
- {
- pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
- }
- }
-
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- {
- pcMesh->mColors[c] = new aiColor4D[iCnt];
- }
- }
-
- if (pMesh->HasBones())
- {
- // assume the number of bones won't change in most cases
- pcMesh->mBones = new aiBone*[pMesh->mNumBones];
-
- // iterate through all bones of the mesh and find those which
- // need to be copied to the splitted mesh
- std::vector<aiVertexWeight> avTempWeights;
- for (unsigned int p = 0; p < pcMesh->mNumBones;++p)
- {
- aiBone* const bone = pcMesh->mBones[p];
- avTempWeights.clear();
- avTempWeights.reserve(bone->mNumWeights / iSubMeshes);
-
- for (unsigned int q = 0; q < bone->mNumWeights;++q)
- {
- aiVertexWeight& weight = bone->mWeights[q];
- if (weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum)
- {
- avTempWeights.push_back(weight);
- weight = avTempWeights.back();
- weight.mVertexId -= iBase;
- }
- }
-
- if (!avTempWeights.empty())
- {
- // we'll need this bone. Copy it ...
- aiBone* pc = new aiBone();
- pcMesh->mBones[pcMesh->mNumBones++] = pc;
- pc->mName = aiString(bone->mName);
- pc->mNumWeights = (unsigned int)avTempWeights.size();
- pc->mOffsetMatrix = bone->mOffsetMatrix;
-
- // no need to reallocate the array for the last submesh.
- // Here we can reuse the (large) source array, although
- // we'll waste some memory
- if (iSubMeshes-1 == i)
- {
- pc->mWeights = bone->mWeights;
- bone->mWeights = NULL;
- }
- else pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- // copy the weights
- ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
- }
- }
- }
-
- // (we will also need to copy the array of indices)
- unsigned int iCurrent = 0;
- for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
- {
- pcMesh->mFaces[p].mNumIndices = 3;
- // allocate a new array
- const unsigned int iTemp = p + iBase;
- const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices;
-
- // setup face type and number of indices
- pcMesh->mFaces[p].mNumIndices = iNumIndices;
- unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
- unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
-
- // need to update the output primitive types
- switch (iNumIndices)
- {
- case 1:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
-
- // and copy the contents of the old array, offset by current base
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pi[v];
- unsigned int iIndexOut = iCurrent++;
- piOut[v] = iIndexOut;
-
- // copy positions
- if (pMesh->mVertices != NULL)
- pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
-
- // copy normals
- if (pMesh->HasNormals())
- pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
-
- // copy tangents/bitangents
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
- pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- if (pMesh->HasTextureCoords( c))
- pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
- }
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
- }
- }
- }
-
- // add the newly created mesh to the list
- avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
- }
-
- // now delete the old mesh data
- delete pMesh;
- }
- else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex()
-{
- LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SplitLargeMeshes) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
-{
- std::vector<std::pair<aiMesh*, unsigned int> > avList;
-
- if (0xffffffff == this->LIMIT)return;
-
- DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex begin");
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- this->SplitMesh(a, pScene->mMeshes[a],avList);
-
- if (avList.size() != pScene->mNumMeshes)
- {
- // it seems something has been splitted. rebuild the mesh list
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)avList.size();
- pScene->mMeshes = new aiMesh*[avList.size()];
-
- for (unsigned int i = 0; i < avList.size();++i)
- pScene->mMeshes[i] = avList[i].first;
-
- // now we need to update all nodes
- SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
- DefaultLogger::get()->info("SplitLargeMeshesProcess_Vertex finished. Meshes have been splitted");
- }
- else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp)
-{
- this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Vertex::SplitMesh(
- unsigned int a,
- aiMesh* pMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
- {
- typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
-
- // build a per-vertex weight list if necessary
- VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);
-
- // we need to split this mesh into sub meshes
- // determine the estimated size of a submesh
- // (this could be too large. Max waste is a single digit percentage)
- const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
- //const unsigned int iOutVertexNum2 = pMesh->mNumVertices /iSubMeshes;
-
- // create a std::vector<unsigned int> to indicate which vertices
- // have already been copied
- std::vector<unsigned int> avWasCopied;
- avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF);
-
- // try to find a good estimate for the number of output faces
- // per mesh. Add 12.5% as buffer
- unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes;
- iEstimatedSize += iEstimatedSize >> 3;
-
- // now generate all submeshes
- unsigned int iBase = 0;
- while (true)
- {
- const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;
-
- aiMesh* pcMesh = new aiMesh;
- pcMesh->mNumVertices = 0;
- pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
-
- // the name carries the adjacency information between the meshes
- pcMesh->mName = pMesh->mName;
-
- typedef std::vector<aiVertexWeight> BoneWeightList;
- if (pMesh->HasBones())
- {
- pcMesh->mBones = new aiBone*[pMesh->mNumBones];
- ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
- }
-
- // clear the temporary helper array
- if (iBase)
- {
- // we can't use memset here we unsigned int needn' be 32 bits
- for (std::vector<unsigned int>::iterator
- iter = avWasCopied.begin(),end = avWasCopied.end();
- iter != end;++iter)
- {
- (*iter) = 0xffffffff;
- }
- }
-
- // output vectors
- std::vector<aiFace> vFaces;
-
- // reserve enough storage for most cases
- if (pMesh->HasPositions())
- {
- pcMesh->mVertices = new aiVector3D[iOutVertexNum];
- }
- if (pMesh->HasNormals())
- {
- pcMesh->mNormals = new aiVector3D[iOutVertexNum];
- }
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents = new aiVector3D[iOutVertexNum];
- pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
- }
- for (unsigned int c = 0; pMesh->HasVertexColors(c);++c)
- {
- pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
- }
- for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c)
- {
- pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
- pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
- }
- vFaces.reserve(iEstimatedSize);
-
- // (we will also need to copy the array of indices)
- while (iBase < pMesh->mNumFaces)
- {
- // allocate a new array
- const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;
-
- // doesn't catch degenerates but is quite fast
- unsigned int iNeed = 0;
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
-
- // check whether we do already have this vertex
- if (0xFFFFFFFF == avWasCopied[iIndex])
- {
- iNeed++;
- }
- }
- if (pcMesh->mNumVertices + iNeed > iOutVertexNum)
- {
- // don't use this face
- break;
- }
-
- vFaces.push_back(aiFace());
- aiFace& rFace = vFaces.back();
-
- // setup face type and number of indices
- rFace.mNumIndices = iNumIndices;
- rFace.mIndices = new unsigned int[iNumIndices];
-
- // need to update the output primitive types
- switch (rFace.mNumIndices)
- {
- case 1:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
-
- // and copy the contents of the old array, offset by current base
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
-
- // check whether we do already have this vertex
- if (0xFFFFFFFF != avWasCopied[iIndex])
- {
- rFace.mIndices[v] = avWasCopied[iIndex];
- continue;
- }
-
- // copy positions
- pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);
-
- // copy normals
- if (pMesh->HasNormals())
- {
- pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
- }
-
- // copy tangents/bitangents
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
- pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- if (pMesh->HasTextureCoords( c))
- {
- pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
- }
- }
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- {
- pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
- }
- }
- // check whether we have bone weights assigned to this vertex
- rFace.mIndices[v] = pcMesh->mNumVertices;
- if (avPerVertexWeights)
- {
- VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
- if ( !table.empty() )
- {
- for (VertexWeightTable::const_iterator
- iter = table.begin();
- iter != table.end();++iter)
- {
- // allocate the bone weight array if necessary
- BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
- if (!pcWeightList)
- {
- pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
- }
- pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
- }
- }
- }
-
- avWasCopied[iIndex] = pcMesh->mNumVertices;
- pcMesh->mNumVertices++;
- }
- iBase++;
- if (pcMesh->mNumVertices == iOutVertexNum)
- {
- // break here. The face is only added if it was complete
- break;
- }
- }
-
- // check which bones we'll need to create for this submesh
- if (pMesh->HasBones())
- {
- aiBone** ppCurrent = pcMesh->mBones;
- for (unsigned int k = 0; k < pMesh->mNumBones;++k)
- {
- // check whether the bone is existing
- BoneWeightList* pcWeightList;
- if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k]))
- {
- aiBone* pcOldBone = pMesh->mBones[k];
- aiBone* pcOut;
- *ppCurrent++ = pcOut = new aiBone();
- pcOut->mName = aiString(pcOldBone->mName);
- pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
- pcOut->mNumWeights = (unsigned int)pcWeightList->size();
- pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights];
-
- // copy the vertex weights
- ::memcpy(pcOut->mWeights,&pcWeightList->operator[](0),
- pcOut->mNumWeights * sizeof(aiVertexWeight));
-
- // delete the temporary bone weight list
- delete pcWeightList;
- pcMesh->mNumBones++;
- }
- }
- }
-
- // copy the face list to the mesh
- pcMesh->mFaces = new aiFace[vFaces.size()];
- pcMesh->mNumFaces = (unsigned int)vFaces.size();
-
- for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
- pcMesh->mFaces[p] = vFaces[p];
-
- // add the newly created mesh to the list
- avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
-
- if (iBase == pMesh->mNumFaces)
- {
- // have all faces ... finish the outer loop, too
- break;
- }
- }
-
- // delete the per-vertex weight list again
- delete[] avPerVertexWeights;
-
- // now delete the old mesh data
- delete pMesh;
- return;
- }
- avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
- return;
-}
diff --git a/3rdparty/assimp/code/SplitLargeMeshes.h b/3rdparty/assimp/code/SplitLargeMeshes.h
deleted file mode 100644
index fd5aec56..00000000
--- a/3rdparty/assimp/code/SplitLargeMeshes.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to split large meshes into submeshes
- */
-#ifndef AI_SPLITLARGEMESHES_H_INC
-#define AI_SPLITLARGEMESHES_H_INC
-
-#include <vector>
-#include "BaseProcess.h"
-
-#include "../include/aiMesh.h"
-#include "../include/aiScene.h"
-
-class SplitLargeMeshesTest;
-namespace Assimp
-{
-
-class SplitLargeMeshesProcess_Triangle;
-class SplitLargeMeshesProcess_Vertex;
-
-// NOTE: If you change these limits, don't forget to change the
-// corresponding values in all Assimp ports
-
-// **********************************************************
-// Java: ConfigProperty.java,
-// ConfigProperty.DEFAULT_VERTEX_SPLIT_LIMIT
-// ConfigProperty.DEFAULT_TRIANGLE_SPLIT_LIMIT
-// **********************************************************
-
-// default limit for vertices
-#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
-# define AI_SLM_DEFAULT_MAX_VERTICES 1000000
-#endif
-
-// default limit for triangles
-#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
-# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000
-#endif
-
-// ---------------------------------------------------------------------------
-/** Postprocessing filter to split large meshes into submeshes
- *
- * Applied BEFORE the JoinVertices-Step occurs.
- * Returns NON-UNIQUE vertices, splits by triangle number.
-*/
-class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess
-{
- friend class Importer;
- friend class SplitLargeMeshesProcess_Vertex;
- friend class ::SplitLargeMeshesTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- SplitLargeMeshesProcess_Triangle();
-
- /** Destructor, private as well */
- ~SplitLargeMeshesProcess_Triangle();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with. A
- * bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
-
- //! Set the split limit - needed for unit testing
- inline void SetLimit(unsigned int l)
- {LIMIT = l;}
-
- //! Get the split limit
- inline unsigned int GetLimit() const
- {return LIMIT;}
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- //! Apply the algorithm to a given mesh
- void SplitMesh (unsigned int a, aiMesh* pcMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
- // -------------------------------------------------------------------
- //! Update a node in the asset after a few of its meshes
- //! have been split
- static void UpdateNode(aiNode* pcNode,
- const std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
-public:
- //! Triangle limit
- unsigned int LIMIT;
-};
-
-
-// ---------------------------------------------------------------------------
-/** Postprocessing filter to split large meshes into submeshes
- *
- * Applied AFTER the JoinVertices-Step occurs.
- * Returns UNIQUE vertices, splits by vertex number.
-*/
-class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess
-{
- friend class Importer;
- friend class ::SplitLargeMeshesTest;
-
-protected:
- /** Constructor to be privately used by Importer */
- SplitLargeMeshesProcess_Vertex();
-
- /** Destructor, private as well */
- ~SplitLargeMeshesProcess_Vertex();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
-
- //! Set the split limit - needed for unit testing
- inline void SetLimit(unsigned int l)
- {LIMIT = l;}
-
- //! Get the split limit
- inline unsigned int GetLimit() const
- {return LIMIT;}
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- //! Apply the algorithm to a given mesh
- void SplitMesh (unsigned int a, aiMesh* pcMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
- // NOTE: Reuse SplitLargeMeshesProcess_Triangle::UpdateNode()
-
-public:
- //! Triangle limit
- unsigned int LIMIT;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_SPLITLARGEMESHES_H_INC
diff --git a/3rdparty/assimp/code/StandardShapes.cpp b/3rdparty/assimp/code/StandardShapes.cpp
deleted file mode 100644
index 028db569..00000000
--- a/3rdparty/assimp/code/StandardShapes.cpp
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file StandardShapes.cpp
- * @brief Implementation of the StandardShapes class
- *
- * The primitive geometry data comes from
- * http://geometrictools.com/Documentation/PlatonicSolids.pdf.
- */
-
-#include "AssimpPCH.h"
-#include "StandardShapes.h"
-
-namespace Assimp {
-
-
-# define ADD_TRIANGLE(n0,n1,n2) \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2);
-
-# define ADD_PENTAGON(n0,n1,n2,n3,n4) \
- if (polygons) \
- { \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2); \
- positions.push_back(n3); \
- positions.push_back(n4); \
- } \
- else \
- { \
- ADD_TRIANGLE(n0, n1, n2) \
- ADD_TRIANGLE(n0, n2, n3) \
- ADD_TRIANGLE(n0, n3, n4) \
- }
-
-# define ADD_QUAD(n0,n1,n2,n3) \
- if (polygons) \
- { \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2); \
- positions.push_back(n3); \
- } \
- else \
- { \
- ADD_TRIANGLE(n0, n1, n2) \
- ADD_TRIANGLE(n0, n2, n3) \
- }
-
-
-// ------------------------------------------------------------------------------------------------
-// Fast subdivision for a mesh whose verts have a magnitude of 1
-void Subdivide(std::vector<aiVector3D>& positions)
-{
- // assume this to be constant - (fixme: must be 1.0? I think so)
- const float fl1 = positions[0].Length();
-
- unsigned int origSize = (unsigned int)positions.size();
- for (unsigned int i = 0 ; i < origSize ; i+=3)
- {
- aiVector3D& tv0 = positions[i];
- aiVector3D& tv1 = positions[i+1];
- aiVector3D& tv2 = positions[i+2];
-
- aiVector3D a = tv0, b = tv1, c = tv2;
- aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1;
- aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1;
- aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1;
-
- tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original
- ADD_TRIANGLE(v1, v2, a);
- ADD_TRIANGLE(v2, v3, c);
- ADD_TRIANGLE(v3, v1, b);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh from given vertex positions
-aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
- unsigned int numIndices)
-{
- if (positions.size() & numIndices || positions.empty() || !numIndices)
- return NULL;
-
- // Determine which kinds of primitives the mesh consists of
- aiMesh* out = new aiMesh();
- switch (numIndices)
- {
- case 1:
- out->mPrimitiveTypes = aiPrimitiveType_POINT;
- break;
- case 2:
- out->mPrimitiveTypes = aiPrimitiveType_LINE;
- break;
- case 3:
- out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- break;
- default:
- out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- break;
- };
-
- out->mNumFaces = (unsigned int)positions.size() / numIndices;
- out->mFaces = new aiFace[out->mNumFaces];
- for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
- {
- aiFace& f = out->mFaces[i];
- f.mNumIndices = numIndices;
- f.mIndices = new unsigned int[numIndices];
- for (unsigned int i = 0; i < numIndices;++i,++a)
- f.mIndices[i] = a;
- }
- out->mNumVertices = (unsigned int)positions.size();
- out->mVertices = new aiVector3D[out->mNumVertices];
- ::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
- std::vector<aiVector3D>&))
-{
- std::vector<aiVector3D> temp;
- unsigned num = (*GenerateFunc)(temp);
- return MakeMesh(temp,num);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
- std::vector<aiVector3D>&, bool))
-{
- std::vector<aiVector3D> temp;
- unsigned num = (*GenerateFunc)(temp,true);
- return MakeMesh(temp,num);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh (unsigned int num, void (*GenerateFunc)(
- unsigned int,std::vector<aiVector3D>&))
-{
- std::vector<aiVector3D> temp;
- (*GenerateFunc)(num,temp);
- return MakeMesh(temp,3);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build an incosahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+60);
-
- const float t = (1.f + 2.236067977f)/2.f;
- const float s = sqrt(1.f + t*t);
-
- const aiVector3D v0 = aiVector3D(t,1.f, 0.f)/s;
- const aiVector3D v1 = aiVector3D(-t,1.f, 0.f)/s;
- const aiVector3D v2 = aiVector3D(t,-1.f, 0.f)/s;
- const aiVector3D v3 = aiVector3D(-t,-1.f, 0.f)/s;
- const aiVector3D v4 = aiVector3D(1.f, 0.f, t)/s;
- const aiVector3D v5 = aiVector3D(1.f, 0.f,-t)/s;
- const aiVector3D v6 = aiVector3D(-1.f, 0.f,t)/s;
- const aiVector3D v7 = aiVector3D(-1.f, 0.f,-t)/s;
- const aiVector3D v8 = aiVector3D(0.f, t, 1.f)/s;
- const aiVector3D v9 = aiVector3D(0.f,-t, 1.f)/s;
- const aiVector3D v10 = aiVector3D(0.f, t,-1.f)/s;
- const aiVector3D v11 = aiVector3D(0.f,-t,-1.f)/s;
-
- ADD_TRIANGLE(v0,v8,v4);
- ADD_TRIANGLE(v0,v5,v10);
- ADD_TRIANGLE(v2,v4,v9);
- ADD_TRIANGLE(v2,v11,v5);
-
- ADD_TRIANGLE(v1,v6,v8);
- ADD_TRIANGLE(v1,v10,v7);
- ADD_TRIANGLE(v3,v9,v6);
- ADD_TRIANGLE(v3,v7,v11);
-
- ADD_TRIANGLE(v0,v10,v8);
- ADD_TRIANGLE(v1,v8,v10);
- ADD_TRIANGLE(v2,v9,v11);
- ADD_TRIANGLE(v3,v11,v9);
-
- ADD_TRIANGLE(v4,v2,v0);
- ADD_TRIANGLE(v5,v0,v2);
- ADD_TRIANGLE(v6,v1,v3);
- ADD_TRIANGLE(v7,v3,v1);
-
- ADD_TRIANGLE(v8,v6,v4);
- ADD_TRIANGLE(v9,v4,v6);
- ADD_TRIANGLE(v10,v5,v7);
- ADD_TRIANGLE(v11,v7,v5);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a dodecahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions,
- bool polygons /*= false*/)
-{
- positions.reserve(positions.size()+108);
-
- const float a = 1.f / 1.7320508f;
- const float b = sqrt((3.f-2.23606797f)/6.f);
- const float c = sqrt((3.f+2.23606797f)/6.f);
-
- const aiVector3D v0 = aiVector3D(a,a,a);
- const aiVector3D v1 = aiVector3D(a,a,-a);
- const aiVector3D v2 = aiVector3D(a,-a,a);
- const aiVector3D v3 = aiVector3D(a,-a,-a);
- const aiVector3D v4 = aiVector3D(-a,a,a);
- const aiVector3D v5 = aiVector3D(-a,a,-a);
- const aiVector3D v6 = aiVector3D(-a,-a,a);
- const aiVector3D v7 = aiVector3D(-a,-a,-a);
- const aiVector3D v8 = aiVector3D(b,c,0.f);
- const aiVector3D v9 = aiVector3D(-b,c,0.f);
- const aiVector3D v10 = aiVector3D(b,-c,0.f);
- const aiVector3D v11 = aiVector3D(-b,-c,0.f);
- const aiVector3D v12 = aiVector3D(c, 0.f, b);
- const aiVector3D v13 = aiVector3D(c, 0.f, -b);
- const aiVector3D v14 = aiVector3D(-c, 0.f, b);
- const aiVector3D v15 = aiVector3D(-c, 0.f, -b);
- const aiVector3D v16 = aiVector3D(0.f, b, c);
- const aiVector3D v17 = aiVector3D(0.f, -b, c);
- const aiVector3D v18 = aiVector3D(0.f, b, -c);
- const aiVector3D v19 = aiVector3D(0.f, -b, -c);
-
- ADD_PENTAGON(v0, v8, v9, v4, v16);
- ADD_PENTAGON(v0, v12, v13, v1, v8);
- ADD_PENTAGON(v0, v16, v17, v2, v12);
- ADD_PENTAGON(v8, v1, v18, v5, v9);
- ADD_PENTAGON(v12, v2, v10, v3, v13);
- ADD_PENTAGON(v16, v4, v14, v6, v17);
- ADD_PENTAGON(v9, v5, v15, v14, v4);
-
- ADD_PENTAGON(v6, v11, v10, v2, v17);
- ADD_PENTAGON(v3, v19, v18, v1, v13);
- ADD_PENTAGON(v7, v15, v5, v18, v19);
- ADD_PENTAGON(v7, v11, v6, v14, v15);
- ADD_PENTAGON(v7, v19, v3, v10, v11);
- return (polygons ? 5 : 3);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build an octahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+24);
-
- const aiVector3D v0 = aiVector3D(1.0f, 0.f, 0.f) ;
- const aiVector3D v1 = aiVector3D(-1.0f, 0.f, 0.f);
- const aiVector3D v2 = aiVector3D(0.f, 1.0f, 0.f);
- const aiVector3D v3 = aiVector3D(0.f, -1.0f, 0.f);
- const aiVector3D v4 = aiVector3D(0.f, 0.f, 1.0f);
- const aiVector3D v5 = aiVector3D(0.f, 0.f, -1.0f);
-
- ADD_TRIANGLE(v4,v0,v2);
- ADD_TRIANGLE(v4,v2,v1);
- ADD_TRIANGLE(v4,v1,v3);
- ADD_TRIANGLE(v4,v3,v0);
-
- ADD_TRIANGLE(v5,v2,v0);
- ADD_TRIANGLE(v5,v1,v2);
- ADD_TRIANGLE(v5,v3,v1);
- ADD_TRIANGLE(v5,v0,v3);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a tetrahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+9);
-
- const float a = 1.41421f/3.f;
- const float b = 2.4494f/3.f;
-
- const aiVector3D v0 = aiVector3D(0.f,0.f,1.f);
- const aiVector3D v1 = aiVector3D(2*a,0,-1.f/3.f);
- const aiVector3D v2 = aiVector3D(-a,b,-1.f/3.f);
- const aiVector3D v3 = aiVector3D(-a,-b,-1.f/3.f);
-
- ADD_TRIANGLE(v0,v1,v2);
- ADD_TRIANGLE(v0,v2,v3);
- ADD_TRIANGLE(v0,v3,v1);
- ADD_TRIANGLE(v1,v3,v2);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a hexahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
- bool polygons /*= false*/)
-{
- positions.reserve(positions.size()+36);
- const float length = 1.f/1.73205080f;
-
- const aiVector3D v0 = aiVector3D(-1.f,-1.f,-1.f)*length;
- const aiVector3D v1 = aiVector3D(1.f,-1.f,-1.f)*length;
- const aiVector3D v2 = aiVector3D(1.f,1.f,-1.f)*length;
- const aiVector3D v3 = aiVector3D(-1.f,1.f,-1.f)*length;
- const aiVector3D v4 = aiVector3D(-1.f,-1.f,1.f)*length;
- const aiVector3D v5 = aiVector3D(1.f,-1.f,1.f)*length;
- const aiVector3D v6 = aiVector3D(1.f,1.f,1.f)*length;
- const aiVector3D v7 = aiVector3D(-1.f,1.f,1.f)*length;
-
- ADD_QUAD(v0,v3,v2,v1);
- ADD_QUAD(v0,v1,v5,v4);
- ADD_QUAD(v0,v4,v7,v3);
- ADD_QUAD(v6,v5,v1,v2);
- ADD_QUAD(v6,v2,v3,v7);
- ADD_QUAD(v6,v7,v4,v5);
- return (polygons ? 4 : 3);
-}
-
-// Cleanup ...
-#undef ADD_TRIANGLE
-#undef ADD_QUAD
-#undef ADD_PENTAGON
-
-// ------------------------------------------------------------------------------------------------
-// Create a subdivision sphere
-void StandardShapes::MakeSphere(unsigned int tess,
- std::vector<aiVector3D>& positions)
-{
- // Reserve enough storage. Every subdivision
- // splits each triangle in 4, the icosahedron consists of 60 verts
- positions.reserve(positions.size()+60 * integer_pow(4, tess));
-
- // Construct an icosahedron to start with
- MakeIcosahedron(positions);
-
- // ... and subdivide it until the requested output
- // tesselation is reached
- for (unsigned int i = 0; i<tess;++i)
- Subdivide(positions);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a cone
-void StandardShapes::MakeCone(float height,float radius1,
- float radius2,unsigned int tess,
- std::vector<aiVector3D>& positions,bool bOpen /*= false */)
-{
- // Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE
- if (tess < 3 || !height)
- return;
-
- size_t old = positions.size();
-
- // No negative radii
- radius1 = ::fabs(radius1);
- radius2 = ::fabs(radius2);
-
- float halfHeight = height / 2;
-
- // radius1 is always the smaller one
- if (radius2 > radius1)
- {
- std::swap(radius2,radius1);
- halfHeight = -halfHeight;
- }
- else old = 0xffffffff;
-
- // Use a large epsilon to check whether the cone is pointy
- if (radius1 < (radius2-radius1)*10e-3f)radius1 = 0.f;
-
- // We will need 3*2 verts per segment + 3*2 verts per segment
- // if the cone is closed
- const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0);
- positions.reserve(positions.size () + mem);
-
- // Now construct all segments
- const float angle_delta = (float)AI_MATH_TWO_PI / tess;
- const float angle_max = (float)AI_MATH_TWO_PI;
-
- float s = 1.f; // cos(angle == 0);
- float t = 0.f; // sin(angle == 0);
-
- for (float angle = 0.f; angle < angle_max; )
- {
- const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 );
- const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 );
-
- const float next = angle + angle_delta;
- float s2 = ::cos(next);
- float t2 = ::sin(next);
-
- const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 );
- const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 );
-
- positions.push_back(v1);
- positions.push_back(v2);
- positions.push_back(v3);
- positions.push_back(v4);
- positions.push_back(v1);
- positions.push_back(v3);
-
- if (!bOpen)
- {
- // generate the end 'cap'
- positions.push_back(aiVector3D(s * radius2, halfHeight, t * radius2 ));
- positions.push_back(aiVector3D(s2 * radius2, halfHeight, t2 * radius2 ));
- positions.push_back(aiVector3D(0.f, halfHeight, 0.f));
-
-
- if (radius1)
- {
- // generate the other end 'cap'
- positions.push_back(aiVector3D(s * radius1, -halfHeight, t * radius1 ));
- positions.push_back(aiVector3D(s2 * radius1, -halfHeight, t2 * radius1 ));
- positions.push_back(aiVector3D(0.f, -halfHeight, 0.f));
-
- }
- }
- s = s2;
- t = t2;
- angle = next;
- }
-
- // Need to flip face order?
- if (0xffffffff != old )
- {
- for (size_t s = old; s < positions.size();s += 3)
- std::swap(positions[s],positions[s+1]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a circle
-void StandardShapes::MakeCircle(float radius, unsigned int tess,
- std::vector<aiVector3D>& positions)
-{
- // Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE
- if (tess < 3 || !radius)
- return;
-
- radius = ::fabs(radius);
-
- // We will need 3 vertices per segment
- positions.reserve(positions.size()+tess*3);
-
- const float angle_delta = (float)AI_MATH_TWO_PI / tess;
- const float angle_max = (float)AI_MATH_TWO_PI;
-
- float s = 1.f; // cos(angle == 0);
- float t = 0.f; // sin(angle == 0);
-
- for (float angle = 0.f; angle < angle_max; )
- {
- positions.push_back(aiVector3D(s * radius,0.f,t * radius));
- angle += angle_delta;
- s = ::cos(angle);
- t = ::sin(angle);
- positions.push_back(aiVector3D(s * radius,0.f,t * radius));
-
- positions.push_back(aiVector3D(0.f,0.f,0.f));
- }
-}
-
-} // ! Assimp
diff --git a/3rdparty/assimp/code/StandardShapes.h b/3rdparty/assimp/code/StandardShapes.h
deleted file mode 100644
index e5b550e3..00000000
--- a/3rdparty/assimp/code/StandardShapes.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Declares a helper class, "StandardShapes" which generates
- * vertices for standard shapes, such as cylnders, cones, spheres ..
- */
-#ifndef AI_STANDARD_SHAPES_H_INC
-#define AI_STANDARD_SHAPES_H_INC
-
-#include <vector>
-
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper class to generate vertex buffers for standard geometric
- * shapes, such as cylinders, cones, boxes, spheres, elipsoids ... .
- */
-class ASSIMP_API StandardShapes
-{
- // class cannot be instanced
- StandardShapes() {}
-
-public:
-
-
- // ----------------------------------------------------------------
- /** Generates a mesh from an array of vertex positions.
- *
- * @param positions List of vertex positions
- * @param numIndices Number of indices per primitive
- * @return Output mesh
- */
- static aiMesh* MakeMesh(const std::vector<aiVector3D>& positions,
- unsigned int numIndices);
-
-
- static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
- (std::vector<aiVector3D>&));
-
- static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
- (std::vector<aiVector3D>&, bool));
-
- static aiMesh* MakeMesh ( unsigned int n, void (*GenerateFunc)
- (unsigned int,std::vector<aiVector3D>&));
-
- // ----------------------------------------------------------------
- /** @brief Generates a hexahedron (cube)
- *
- * Hexahedrons can be scaled on all axes.
- * @param positions Receives output triangles.
- * @param polygons If you pass true here quads will be returned
- * @return Number of vertices per face
- */
- static unsigned int MakeHexahedron(
- std::vector<aiVector3D>& positions,
- bool polygons = false);
-
- // ----------------------------------------------------------------
- /** @brief Generates an icosahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeIcosahedron(
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a dodecahedron
- *
- * @param positions Receives output triangles
- * @param polygons If you pass true here pentagons will be returned
- * @return Number of vertices per face
- */
- static unsigned int MakeDodecahedron(
- std::vector<aiVector3D>& positions,
- bool polygons = false);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates an octahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeOctahedron(
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a tetrahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeTetrahedron(
- std::vector<aiVector3D>& positions);
-
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a sphere
- *
- * @param tess Number of subdivions - 0 generates a octahedron
- * @param positions Receives output triangles.
- */
- static void MakeSphere(unsigned int tess,
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a cone or a cylinder, either open or closed.
- *
- * @code
- *
- * |-----| <- radius 1
- *
- * __x__ <- ] ^
- * / \ | height |
- * / \ | Y
- * / \ |
- * / \ |
- * /______x______\ <- ] <- end cap
- *
- * |-------------| <- radius 2
- *
- * @endcode
- *
- * @param height Height of the cone
- * @param radius1 First radius
- * @param radius2 Second radius
- * @param tess Number of triangles.
- * @param bOpened true for an open cone/cylinder. An open shape has
- * no 'end caps'
- * @param positions Receives output triangles
- */
- static void MakeCone(float height,float radius1,
- float radius2,unsigned int tess,
- std::vector<aiVector3D>& positions,bool bOpen= false);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a flat circle
- *
- * The circle is constructed in the planed formed by the x,z
- * axes of the cartesian coordinate system.
- *
- * @param radius Radius of the circle
- * @param tess Number of segments.
- * @param positions Receives output triangles.
- */
- static void MakeCircle(float radius, unsigned int tess,
- std::vector<aiVector3D>& positions);
-
-};
-} // ! Assimp
-
-#endif // !! AI_STANDARD_SHAPES_H_INC
diff --git a/3rdparty/assimp/code/StdOStreamLogStream.h b/3rdparty/assimp/code/StdOStreamLogStream.h
deleted file mode 100644
index b80451f0..00000000
--- a/3rdparty/assimp/code/StdOStreamLogStream.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef AI_STROSTREAMLOGSTREAM_H_INC
-#define AI_STROSTREAMLOGSTREAM_H_INC
-
-#include "../include/LogStream.h"
-#include <ostream>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @class StdOStreamLogStream
- * @brief Logs into a std::ostream
- */
-class StdOStreamLogStream : public LogStream
-{
-public:
- /** @brief Construction from an existing std::ostream
- * @param _ostream Output stream to be used
- */
- StdOStreamLogStream(std::ostream& _ostream);
-
- /** @brief Destructor */
- ~StdOStreamLogStream();
-
- /** @brief Writer */
- void write(const char* message);
-private:
- std::ostream& ostream;
-};
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline StdOStreamLogStream::StdOStreamLogStream(std::ostream& _ostream)
- : ostream (_ostream)
-{}
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline StdOStreamLogStream::~StdOStreamLogStream()
-{}
-
-// ---------------------------------------------------------------------------
-// Write method
-inline void StdOStreamLogStream::write(const char* message)
-{
- ostream << message;
- ostream.flush();
-}
-
-// ---------------------------------------------------------------------------
-} // Namespace Assimp
-
-#endif // guard
diff --git a/3rdparty/assimp/code/StreamReader.h b/3rdparty/assimp/code/StreamReader.h
deleted file mode 100644
index 8e171c39..00000000
--- a/3rdparty/assimp/code/StreamReader.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Defines the StreamReader class which reads data from
- * a binary stream with a well-defined endianess. */
-
-#ifndef AI_STREAMREADER_H_INCLUDED
-#define AI_STREAMREADER_H_INCLUDED
-
-#include "ByteSwap.h"
-namespace Assimp {
- namespace Intern {
-
-// --------------------------------------------------------------------------------------------
-template <typename T, bool doit>
-struct ByteSwapper {
- void operator() (T* inout) {
- ByteSwap::Swap(inout);
- }
-};
-
-template <typename T>
-struct ByteSwapper<T,false> {
- void operator() (T*) {
- }
-};
-
-// --------------------------------------------------------------------------------------------
-template <bool SwapEndianess, typename T, bool RuntimeSwitch>
-struct Getter {
- void operator() (T* inout, bool le) {
-#ifdef AI_BUILD_BIG_ENDIAN
- le = le;
-#else
- le = !le;
-#endif
- if (le) {
- ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
- }
- else ByteSwapper<T,false> () (inout);
- }
-};
-
-template <bool SwapEndianess, typename T>
-struct Getter<SwapEndianess,T,false> {
- void operator() (T* inout, bool /* le */) {
-
- // static branch
- ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
- }
-};
-} // end Intern
-
-// --------------------------------------------------------------------------------------------
-/** Wrapper class around IOStream to allow for consistent reading of binary data in both
- * little and big endian format. Don't attempt to instance the template directly. Use
- * StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a
- * BE stream. The class expects that the endianess of any input data is known at
- * compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements
- * runtime endianess conversions for text files).
- *
- * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/
-// --------------------------------------------------------------------------------------------
-template <bool SwapEndianess = false, bool RuntimeSwitch = false>
-class StreamReader
-{
-
-public:
-
- // FIXME: use these data types throughout the whole library,
- // then change them to 64 bit values :-)
-
- typedef int diff;
- typedef unsigned int pos;
-
-public:
-
-
- // ---------------------------------------------------------------------
- /** Construction from a given stream with a well-defined endianess.
- *
- * The StreamReader holds a permanent strong reference to the
- * stream, which is released upon destruction.
- * @param stream Input stream. The stream is not restarted if
- * its file pointer is not at 0. Instead, the stream reader
- * reads from the current position to the end of the stream.
- * @param le If @c RuntimeSwitch is true: specifies whether the
- * stream is in little endian byte order. Otherwise the
- * endianess information is contained in the @c SwapEndianess
- * template parameter and this parameter is meaningless. */
- StreamReader(boost::shared_ptr<IOStream> stream, bool le = false)
- : stream(stream)
- , le(le)
- {
- _Begin();
- }
-
- // ---------------------------------------------------------------------
- StreamReader(IOStream* stream, bool le = false)
- : stream(boost::shared_ptr<IOStream>(stream))
- , le(le)
- {
- _Begin();
- }
-
- // ---------------------------------------------------------------------
- ~StreamReader() {
- delete[] buffer;
- }
-
-public:
-
- // deprecated, use overloaded operator>> instead
-
- // ---------------------------------------------------------------------
- /** Read a float from the stream */
- float GetF4()
- {
- return Get<float>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a double from the stream */
- double GetF8() {
- return Get<double>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 16 bit integer from the stream */
- int16_t GetI2() {
- return Get<int16_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 8 bit integer from the stream */
- int8_t GetI1() {
- return Get<int8_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read an signed 32 bit integer from the stream */
- int32_t GetI4() {
- return Get<int32_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 64 bit integer from the stream */
- int64_t GetI8() {
- return Get<int64_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 16 bit integer from the stream */
- uint16_t GetU2() {
- return Get<uint16_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 8 bit integer from the stream */
- uint8_t GetU1() {
- return Get<uint8_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read an unsigned 32 bit integer from the stream */
- uint32_t GetU4() {
- return Get<uint32_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 64 bit integer from the stream */
- uint64_t GetU8() {
- return Get<uint64_t>();
- }
-
-public:
-
- // ---------------------------------------------------------------------
- /** Get the remaining stream size (to the end of the srream) */
- unsigned int GetRemainingSize() const {
- return (unsigned int)(end - current);
- }
-
-
- // ---------------------------------------------------------------------
- /** Get the remaining stream size (to the current read limit). The
- * return value is the remaining size of the stream if no custom
- * read limit has been set. */
- unsigned int GetRemainingSizeToLimit() const {
- return (unsigned int)(limit - current);
- }
-
-
- // ---------------------------------------------------------------------
- /** Increase the file pointer (relative seeking) */
- void IncPtr(int plus) {
- current += plus;
- if (current > limit) {
- throw DeadlyImportError("End of file or read limit was reached");
- }
- }
-
- // ---------------------------------------------------------------------
- /** Get the current file pointer */
- int8_t* GetPtr() const {
- return current;
- }
-
-
- // ---------------------------------------------------------------------
- /** Set current file pointer (Get it from #GetPtr). This is if you
- * prefer to do pointer arithmetics on your own or want to copy
- * large chunks of data at once.
- * @param p The new pointer, which is validated against the size
- * limit and buffer boundaries. */
- void SetPtr(int8_t* p) {
-
- current = p;
- if (current > limit || current < buffer) {
- throw DeadlyImportError("End of file or read limit was reached");
- }
- }
-
- // ---------------------------------------------------------------------
- /** Copy n bytes to an external buffer
- * @param out Destination for copying
- * @param bytes Number of bytes to copy */
- void CopyAndAdvance(void* out, size_t bytes) {
-
- int8_t* ur = GetPtr();
- SetPtr(ur+bytes); // fire exception if eof
-
- memcpy(out,ur,bytes);
- }
-
-
- // ---------------------------------------------------------------------
- /** Get the current offset from the beginning of the file */
- int GetCurrentPos() const {
- return (unsigned int)(current - buffer);
- }
-
- void SetCurrentPos(size_t pos) {
- SetPtr(buffer + pos);
- }
-
- // ---------------------------------------------------------------------
- /** Setup a temporary read limit
- *
- * @param limit Maximum number of bytes to be read from
- * the beginning of the file. Passing 0xffffffff
- * resets the limit to the original end of the stream. */
- void SetReadLimit(unsigned int _limit) {
-
- if (0xffffffff == _limit) {
- limit = end;
- return;
- }
-
- limit = buffer + _limit;
- if (limit > end) {
- throw DeadlyImportError("StreamReader: Invalid read limit");
- }
- }
-
- // ---------------------------------------------------------------------
- /** Get the current read limit in bytes. Reading over this limit
- * accidentially raises an exception. */
- int GetReadLimit() const {
- return (unsigned int)(limit - buffer);
- }
-
- // ---------------------------------------------------------------------
- /** Skip to the read limit in bytes. Reading over this limit
- * accidentially raises an exception. */
- void SkipToReadLimit() {
- current = limit;
- }
-
- // ---------------------------------------------------------------------
- /** overload operator>> and allow chaining of >> ops. */
- template <typename T>
- StreamReader& operator >> (T& f) {
- f = Get<T>();
- return *this;
- }
-
-private:
-
- // ---------------------------------------------------------------------
- /** Generic read method. ByteSwap::Swap(T*) *must* be defined */
- template <typename T>
- T Get() {
- if (current + sizeof(T) > limit) {
- throw DeadlyImportError("End of file or stream limit was reached");
- }
-
- T f;
- memcpy(&f, current, sizeof(T));
- Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
-
- current += sizeof(T);
- return f;
- }
-
- // ---------------------------------------------------------------------
- void _Begin() {
- if (!stream) {
- throw DeadlyImportError("StreamReader: Unable to open file");
- }
-
- const size_t s = stream->FileSize() - stream->Tell();
- if (!s) {
- throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
- }
-
- current = buffer = new int8_t[s];
- stream->Read(current,s,1);
- end = limit = &buffer[s];
- }
-
-private:
-
-
- boost::shared_ptr<IOStream> stream;
- int8_t *buffer, *current, *end, *limit;
- bool le;
-};
-
-
-// --------------------------------------------------------------------------------------------
-// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
-#ifdef AI_BUILD_BIG_ENDIAN
- typedef StreamReader<true> StreamReaderLE;
- typedef StreamReader<false> StreamReaderBE;
-#else
- typedef StreamReader<true> StreamReaderBE;
- typedef StreamReader<false> StreamReaderLE;
-#endif
-
-// `dynamic` StreamReader. The byte order of the input data is specified in the
-// c'tor. This involves runtime branching and might be a little bit slower.
-typedef StreamReader<true,true> StreamReaderAny;
-
-} // end namespace Assimp
-
-#endif // !! AI_STREAMREADER_H_INCLUDED
diff --git a/3rdparty/assimp/code/StringComparison.h b/3rdparty/assimp/code/StringComparison.h
deleted file mode 100644
index b885606a..00000000
--- a/3rdparty/assimp/code/StringComparison.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Definition of platform independent string workers:
-
- ASSIMP_itoa10
- ASSIMP_stricmp
- ASSIMP_strincmp
-
- These functions are not consistently available on all platforms,
- or the provided implementations behave too differently.
-*/
-#ifndef INCLUDED_AI_STRING_WORKERS_H
-#define INCLUDED_AI_STRING_WORKERS_H
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-/** @brief itoa with a fixed base 10
- * 'itoa' is not consistently available on all platforms so it is quite useful
- * to have a small replacement function here. No need to use a full sprintf()
- * if we just want to print a number ...
- * @param out Output buffer
- * @param max Maximum number of characters to be written, including '\0'.
- * This parameter may not be 0.
- * @param number Number to be written
- * @return Length of the output string, excluding the '\0'
- */
-inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
-{
- ai_assert(NULL != out);
-
- // write the unary minus to indicate we have a negative number
- unsigned int written = 1u;
- if (number < 0 && written < max) {
- *out++ = '-';
- ++written;
- number = -number;
- }
-
- // We begin with the largest number that is not zero.
- int32_t cur = 1000000000; // 2147483648
- bool mustPrint = false;
- while (written < max) {
-
- const unsigned int digit = number / cur;
- if (mustPrint || digit > 0 || 1 == cur) {
- // print all future zeroes from now
- mustPrint = true;
-
- *out++ = '0'+digit;
-
- ++written;
- number -= digit*cur;
- if (1 == cur) {
- break;
- }
- }
- cur /= 10;
- }
-
- // append a terminal zero
- *out++ = '\0';
- return written-1;
-}
-
-// -------------------------------------------------------------------------------
-/** @brief itoa with a fixed base 10 (Secure template overload)
- * The compiler should choose this function if he or she is able to determine the
- * size of the array automatically.
- */
-template <size_t length>
-inline unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number)
-{
- return ASSIMP_itoa10(out,length,number);
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to do platform independent string comparison.
- *
- * This is required since stricmp() is not consistently available on
- * all platforms. Some platforms use the '_' prefix, others don't even
- * have such a function.
- *
- * @param s1 First input string
- * @param s2 Second input string
- * @return 0 if the given strings are identical
- */
-inline int ASSIMP_stricmp(const char *s1, const char *s2)
-{
- ai_assert(NULL != s1 && NULL != s2);
-
-#if (defined _MSC_VER)
-
- return ::_stricmp(s1,s2);
-#elif defined( __GNUC__ )
-
- return ::strcasecmp(s1,s2);
-#else
-
- register char c1, c2;
- do {
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- }
- while ( c1 && (c1 == c2) );
- return c1 - c2;
-#endif
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Case independent comparison of two std::strings
- *
- * @param a First string
- * @param b Second string
- * @return 0 if a == b
- */
-inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
-{
- register int i = (int)b.length()-(int)a.length();
- return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str()));
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to do platform independent string comparison.
- *
- * This is required since strincmp() is not consistently available on
- * all platforms. Some platforms use the '_' prefix, others don't even
- * have such a function.
- *
- * @param s1 First input string
- * @param s2 Second input string
- * @param n Macimum number of characters to compare
- * @return 0 if the given strings are identical
- */
-inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
-{
- ai_assert(NULL != s1 && NULL != s2);
- if (!n)return 0;
-
-#if (defined _MSC_VER)
-
- return ::_strnicmp(s1,s2,n);
-
-#elif defined( __GNUC__ )
-
- return ::strncasecmp(s1,s2, n);
-
-#else
- register char c1, c2;
- unsigned int p = 0;
- do
- {
- if (p++ >= n)return 0;
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- }
- while ( c1 && (c1 == c2) );
-
- return c1 - c2;
-#endif
-}
-
-
-// -------------------------------------------------------------------------------
-/** @brief Evaluates an integer power
- *
- * todo: move somewhere where it fits better in than here
- */
-inline unsigned int integer_pow (unsigned int base, unsigned int power)
-{
- unsigned int res = 1;
- for (unsigned int i = 0; i < power;++i)
- res *= base;
-
- return res;
-}
-} // end of namespace
-
-#endif // ! AI_STRINGCOMPARISON_H_INC
diff --git a/3rdparty/assimp/code/Subdivision.cpp b/3rdparty/assimp/code/Subdivision.cpp
deleted file mode 100644
index 1535813d..00000000
--- a/3rdparty/assimp/code/Subdivision.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-
-#include "Subdivision.h"
-#include "SceneCombiner.h"
-#include "SpatialSort.h"
-#include "ProcessHelper.h"
-#include "Vertex.h"
-
-using namespace Assimp;
-void mydummy() {}
-
-// ------------------------------------------------------------------------------------------------
-/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The
- * implementation is basing on recursive refinement. Directly evaluating the result is also
- * possibel and much quicker, but it depends on lengthy matrix lookup tables. */
-// ------------------------------------------------------------------------------------------------
-class CatmullClarkSubdivider : public Subdivider
-{
-
-public:
-
- void Subdivide (const aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
- void Subdivide (const aiMesh* const * smesh, size_t nmesh,
- aiMesh** out, unsigned int num, bool discard_input);
-
- // ---------------------------------------------------------------------------
- /** Intermediate description of an edge between two corners of a polygon*/
- // ---------------------------------------------------------------------------
- struct Edge
- {
- Edge()
- : ref(0)
- {}
- Vertex edge_point, midpoint;
- unsigned int ref;
- };
-
-
-
- typedef std::vector<unsigned int> UIntVector;
- typedef std::map<uint64_t,Edge> EdgeMap;
-
- // ---------------------------------------------------------------------------
- // Hashing function to derive an index into an #EdgeMap from two given
- // 'unsigned int' vertex coordinates (!!distinct coordinates - same
- // vertex position == same index!!).
- // NOTE - this leads to rare hash collisions if a) sizeof(unsigned int)>4
- // and (id[0]>2^32-1 or id[0]>2^32-1).
- // MAKE_EDGE_HASH() uses temporaries, so INIT_EDGE_HASH() needs to be put
- // at the head of every function which is about to use MAKE_EDGE_HASH().
- // Reason is that the hash is that hash construction needs to hold the
- // invariant id0<id1 to identify an edge - else two hashes would refer
- // to the same edge.
- // ---------------------------------------------------------------------------
-#define MAKE_EDGE_HASH(id0,id1) (eh_tmp0__=id0,eh_tmp1__=id1,\
- (eh_tmp0__<eh_tmp1__?std::swap(eh_tmp0__,eh_tmp1__):mydummy()),(uint64_t)eh_tmp0__^((uint64_t)eh_tmp1__<<32u))
-
-
-#define INIT_EDGE_HASH_TEMPORARIES()\
- unsigned int eh_tmp0__, eh_tmp1__;
-
-private:
-
- void InternSubdivide (const aiMesh* const * smesh,
- size_t nmesh,aiMesh** out, unsigned int num);
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Construct a subdivider of a specific type
-Subdivider* Subdivider::Create (Algorithm algo)
-{
- switch (algo)
- {
- case CATMULL_CLARKE:
- return new CatmullClarkSubdivider();
- };
-
- ai_assert(false);
- return NULL; // shouldn't happen
-}
-
-// ------------------------------------------------------------------------------------------------
-// Call the Catmull Clark subdivision algorithm for one mesh
-void CatmullClarkSubdivider::Subdivide (
- const aiMesh* mesh,
- aiMesh*& out,
- unsigned int num,
- bool discard_input
- )
-{
- assert(mesh != out);
- Subdivide(&mesh,1,&out,num,discard_input);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Call the Catmull Clark subdivision algorithm for multiple meshes
-void CatmullClarkSubdivider::Subdivide (
- const aiMesh* const * smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num,
- bool discard_input
- )
-{
- ai_assert(NULL != smesh && NULL != out);
-
- // course, both regions may not overlap
- assert(smesh<out || smesh+nmesh>out+nmesh);
- if (!num) {
-
- // No subdivision at all. Need to copy all the meshes .. argh.
- if (discard_input) {
- for (size_t s = 0; s < nmesh; ++s) {
- out[s] = const_cast<aiMesh*>( smesh[s] );
- const_cast<aiMesh*&>( smesh[s] ) = NULL;
- }
- }
- else {
- for (size_t s = 0; s < nmesh; ++s) {
- SceneCombiner::Copy(out+s,smesh[s]);
- }
- }
- return;
- }
-
- std::vector<const aiMesh*> inmeshes;
- std::vector<aiMesh*> outmeshes;
- std::vector<unsigned int> maptbl;
-
- inmeshes.reserve(nmesh);
- outmeshes.reserve(nmesh);
- maptbl.reserve(nmesh);
-
- // Remove pure line and point meshes from the working set to reduce the
- // number of edge cases the subdivider is forced to deal with. Line and
- // point meshes are simply passed through.
- for (size_t s = 0; s < nmesh; ++s) {
- const aiMesh* i = smesh[s];
- // FIX - mPrimitiveTypes might not yet be initialized
- if (i->mPrimitiveTypes && (i->mPrimitiveTypes & (aiPrimitiveType_LINE|aiPrimitiveType_POINT))==i->mPrimitiveTypes) {
- DefaultLogger::get()->debug("Catmull-Clark Subdivider: Skipping pure line/point mesh");
-
- if (discard_input) {
- out[s] = const_cast<aiMesh*>( i );
- const_cast<aiMesh*&>( smesh[s] ) = NULL;
- }
- else {
- SceneCombiner::Copy(out+s,i);
- }
- continue;
- }
-
- outmeshes.push_back(NULL);inmeshes.push_back(i);
- maptbl.push_back(s);
- }
-
- // Do the actual subdivision on the preallocated storage. InternSubdivide
- // *always* assumes that enough storage is available, it does not bother
- // checking any ranges.
- ai_assert(inmeshes.size()==outmeshes.size()&&inmeshes.size()==maptbl.size());
- if (inmeshes.empty()) {
- DefaultLogger::get()->warn("Catmull-Clark Subdivider: Pure point/line scene, I can't do anything");
- return;
- }
- InternSubdivide(&inmeshes.front(),inmeshes.size(),&outmeshes.front(),num);
- for (unsigned int i = 0; i < maptbl.size(); ++i) {
- ai_assert(outmeshes[i]);
- out[maptbl[i]] = outmeshes[i];
- }
-
- if (discard_input) {
- for (size_t s = 0; s < nmesh; ++s) {
- delete smesh[s];
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further
-// optimizations (except we're using some nice LUTs). A description of the algorithm can be found
-// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface
-//
-// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's
-// expected total runtime complexity. The implementation is able to work in-place on the same
-// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate
-// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings).
-// Previous data is replaced/deleted then.
-// ------------------------------------------------------------------------------------------------
-void CatmullClarkSubdivider::InternSubdivide (
- const aiMesh* const * smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num
- )
-{
- ai_assert(NULL != smesh && NULL != out);
- INIT_EDGE_HASH_TEMPORARIES();
-
- // no subdivision requested or end of recursive refinement
- if (!num) {
- return;
- }
-
- UIntVector maptbl;
- SpatialSort spatial;
-
- // ---------------------------------------------------------------------
- // 0. Offset table to index all meshes continously , generate a spatially
- // sorted representation of all vertices in all meshes.
- // ---------------------------------------------------------------------
- typedef std::pair<unsigned int,unsigned int> IntPair;
- std::vector<IntPair> moffsets(nmesh);
- unsigned int totfaces = 0, totvert = 0;
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
-
- spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false);
- moffsets[t] = IntPair(totfaces,totvert);
-
- totfaces += mesh->mNumFaces;
- totvert += mesh->mNumVertices;
- }
-
- spatial.Finalize();
- const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh));
-
-
-#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx)
-#define FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx)
-
- // ---------------------------------------------------------------------
- // 1. Compute the centroid point for all faces
- // ---------------------------------------------------------------------
- std::vector<Vertex> centroids(totfaces);
- unsigned int nfacesout = 0;
- for (size_t t = 0, n = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
- for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n)
- {
- const aiFace& face = mesh->mFaces[i];
- Vertex& c = centroids[n];
-
- for (unsigned int a = 0; a < face.mNumIndices;++a) {
- c += Vertex(mesh,face.mIndices[a]);
- }
-
- c /= static_cast<float>(face.mNumIndices);
- nfacesout += face.mNumIndices;
- }
- }
-
- EdgeMap edges;
-
- // ---------------------------------------------------------------------
- // 2. Set each edge point to be the average of all neighbouring
- // face points and original points. Every edge exists twice
- // if there is a neighboring face.
- // ---------------------------------------------------------------------
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
-
- for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
- const aiFace& face = mesh->mFaces[i];
-
- for (unsigned int p =0; p< face.mNumIndices; ++p) {
- const unsigned int id[] = {
- face.mIndices[p],
- face.mIndices[p==face.mNumIndices-1?0:p+1]
- };
- const unsigned int mp[] = {
- maptbl[FLATTEN_VERTEX_IDX(t,id[0])],
- maptbl[FLATTEN_VERTEX_IDX(t,id[1])]
- };
-
- Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])];
- e.ref++;
- if (e.ref<=2) {
- if (e.ref==1) { // original points (end points) - add only once
- e.edge_point = e.midpoint = Vertex(mesh,id[0])+Vertex(mesh,id[1]);
- e.midpoint *= 0.5f;
- }
- e.edge_point += centroids[FLATTEN_FACE_IDX(t,i)];
- }
- }
- }
- }
-
- // ---------------------------------------------------------------------
- // 3. Normalize edge points
- // ---------------------------------------------------------------------
- {unsigned int bad_cnt = 0;
- for (EdgeMap::iterator it = edges.begin(); it != edges.end(); ++it) {
- if ((*it).second.ref < 2) {
- ai_assert((*it).second.ref);
- ++bad_cnt;
- }
- (*it).second.edge_point *= 1.f/((*it).second.ref+2.f);
- }
-
- if (bad_cnt) {
- // Report the number of bad edges. bad edges are referenced by less than two
- // faces in the mesh. They occur at outer model boundaries in non-closed
- // shapes.
- char tmp[512];
- sprintf(tmp,"Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
- bad_cnt,static_cast<unsigned int>(edges.size()));
-
- DefaultLogger::get()->debug(tmp);
- }}
-
- // ---------------------------------------------------------------------
- // 4. Compute a vertex-face adjacency table. We can't reuse the code
- // from VertexTriangleAdjacency because we need the table for multiple
- // meshes and out vertex indices need to be mapped to distinct values
- // first.
- // ---------------------------------------------------------------------
- UIntVector faceadjac(nfacesout), cntadjfac(maptbl.size(),0), ofsadjvec(maptbl.size()+1,0); {
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
-
- const aiFace& f = minp->mFaces[i];
- for (unsigned int n = 0; n < f.mNumIndices; ++n) {
- ++cntadjfac[maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]];
- }
- }
- }
- unsigned int cur = 0;
- for (size_t i = 0; i < cntadjfac.size(); ++i) {
- ofsadjvec[i+1] = cur;
- cur += cntadjfac[i];
- }
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
-
- const aiFace& f = minp->mFaces[i];
- for (unsigned int n = 0; n < f.mNumIndices; ++n) {
- faceadjac[ofsadjvec[1+maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]++] = FLATTEN_FACE_IDX(t,i);
- }
- }
- }
-
- // check the other way round for consistency
-#ifdef _DEBUG
-
- for (size_t t = 0; t < ofsadjvec.size()-1; ++t) {
- for (unsigned int m = 0; m < cntadjfac[t]; ++m) {
- const unsigned int fidx = faceadjac[ofsadjvec[t]+m];
- ai_assert(fidx < totfaces);
- for (size_t n = 1; n < nmesh; ++n) {
-
- if (moffsets[n].first > fidx) {
- const aiMesh* msh = smesh[--n];
- const aiFace& f = msh->mFaces[fidx-moffsets[n].first];
-
- bool haveit = false;
- for (unsigned int i = 0; i < f.mNumIndices; ++i) {
- if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) {
- haveit = true; break;
- }
- }
- ai_assert(haveit);
- break;
- }
- }
- }
- }
-
-#endif
- }
-
-#define GET_ADJACENT_FACES_AND_CNT(vidx,fstartout,numout) \
- fstartout = &faceadjac[ofsadjvec[vidx]], numout = cntadjfac[vidx]
-
- typedef std::pair<bool,Vertex> TouchedOVertex;
- std::vector<TouchedOVertex > new_points(num_unique,TouchedOVertex(false,Vertex()));
- // ---------------------------------------------------------------------
- // 5. Spawn a quad from each face point to the corresponding edge points
- // the original points being the fourth quad points.
- // ---------------------------------------------------------------------
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- aiMesh* const mout = out[t] = new aiMesh();
-
- for (unsigned int a = 0; a < minp->mNumFaces; ++a) {
- mout->mNumFaces += minp->mFaces[a].mNumIndices;
- }
-
- // We need random access to the old face buffer, so reuse is not possible.
- mout->mFaces = new aiFace[mout->mNumFaces];
-
- mout->mNumVertices = mout->mNumFaces*4;
- mout->mVertices = new aiVector3D[mout->mNumVertices];
-
- // quads only, keep material index
- mout->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- mout->mMaterialIndex = minp->mMaterialIndex;
-
- if (minp->HasNormals()) {
- mout->mNormals = new aiVector3D[mout->mNumVertices];
- }
-
- if (minp->HasTangentsAndBitangents()) {
- mout->mTangents = new aiVector3D[mout->mNumVertices];
- mout->mBitangents = new aiVector3D[mout->mNumVertices];
- }
-
- for (unsigned int i = 0; minp->HasTextureCoords(i); ++i) {
- mout->mTextureCoords[i] = new aiVector3D[mout->mNumVertices];
- mout->mNumUVComponents[i] = minp->mNumUVComponents[i];
- }
-
- for (unsigned int i = 0; minp->HasVertexColors(i); ++i) {
- mout->mColors[i] = new aiColor4D[mout->mNumVertices];
- }
-
- mout->mNumVertices = mout->mNumFaces<<2u;
- for (unsigned int i = 0, v = 0, n = 0; i < minp->mNumFaces;++i) {
-
- const aiFace& face = minp->mFaces[i];
- for (unsigned int a = 0; a < face.mNumIndices;++a) {
-
- // Get a clean new face.
- aiFace& faceOut = mout->mFaces[n++];
- faceOut.mIndices = new unsigned int [faceOut.mNumIndices = 4];
-
- // Spawn a new quadrilateral (ccw winding) for this original point between:
- // a) face centroid
- centroids[FLATTEN_FACE_IDX(t,i)].SortBack(mout,faceOut.mIndices[0]=v++);
-
- // b) adjacent edge on the left, seen from the centroid
- const Edge& e0 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
- maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a==face.mNumIndices-1?0:a+1])
- ])]; // fixme: replace with mod face.mNumIndices?
-
- // c) adjacent edge on the right, seen from the centroid
- const Edge& e1 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
- maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[!a?face.mNumIndices-1:a-1])
- ])]; // fixme: replace with mod face.mNumIndices?
-
- e0.edge_point.SortBack(mout,faceOut.mIndices[3]=v++);
- e1.edge_point.SortBack(mout,faceOut.mIndices[1]=v++);
-
- // d= original point P with distinct index i
- // F := 0
- // R := 0
- // n := 0
- // for each face f containing i
- // F := F+ centroid of f
- // R := R+ midpoint of edge of f from i to i+1
- // n := n+1
- //
- // (F+2R+(n-3)P)/n
- const unsigned int org = maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])];
- TouchedOVertex& ov = new_points[org];
-
- if (!ov.first) {
- ov.first = true;
-
- const unsigned int* adj; unsigned int cnt;
- GET_ADJACENT_FACES_AND_CNT(org,adj,cnt);
-
- if (cnt < 3) {
- ov.second = Vertex(minp,face.mIndices[a]);
- }
- else {
-
- Vertex F,R;
- for (unsigned int o = 0; o < cnt; ++o) {
- ai_assert(adj[o] < totfaces);
- F += centroids[adj[o]];
-
- // adj[0] is a global face index - search the face in the mesh list
- const aiMesh* mp = NULL;
- size_t nidx;
-
- if (adj[o] < moffsets[0].first) {
- mp = smesh[nidx=0];
- }
- else {
- for (nidx = 1; nidx<= nmesh; ++nidx) {
- if (nidx == nmesh ||moffsets[nidx].first > adj[o]) {
- mp = smesh[--nidx];
- break;
- }
- }
- }
-
- ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces);
- const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first];
-# ifdef _DEBUG
- bool haveit = false;
-# endif
-
- // find our original point in the face
- for (unsigned int m = 0; m < f.mNumIndices; ++m) {
- if (maptbl[FLATTEN_VERTEX_IDX(nidx,f.mIndices[m])] == org) {
-
- // add *both* edges. this way, we can be sure that we add
- // *all* adjacent edges to R. In a closed shape, every
- // edge is added twice - so we simply leave out the
- // factor 2.f in the amove formula and get the right
- // result.
-
- const Edge& c0 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
- nidx,f.mIndices[!m?f.mNumIndices-1:m-1])])];
- // fixme: replace with mod face.mNumIndices?
-
- const Edge& c1 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
- nidx,f.mIndices[m==f.mNumIndices-1?0:m+1])])];
- // fixme: replace with mod face.mNumIndices?
- R += c0.midpoint+c1.midpoint;
-
-# ifdef _DEBUG
- haveit = true;
-# endif
- break;
- }
- }
-
- // this invariant *must* hold if the vertex-to-face adjacency table is valid
-#ifdef _DEBUG
- ai_assert(haveit);
-#endif
- }
-
- const float div = static_cast<float>(cnt), divsq = 1.f/(div*div);
- ov.second = Vertex(minp,face.mIndices[a])*((div-3.f) / div) + R*divsq + F*divsq;
- }
- }
- ov.second.SortBack(mout,faceOut.mIndices[2]=v++);
- }
- }
- }
-
- // ---------------------------------------------------------------------
- // 7. Apply the next subdivision step.
- // ---------------------------------------------------------------------
- if (num != 1) {
- std::vector<aiMesh*> tmp(nmesh);
- InternSubdivide (out,nmesh,&tmp.front(),num-1);
- for (size_t i = 0; i < nmesh; ++i) {
- delete out[i];
- out[i] = tmp[i];
- }
- }
-}
diff --git a/3rdparty/assimp/code/Subdivision.h b/3rdparty/assimp/code/Subdivision.h
deleted file mode 100644
index fb67001d..00000000
--- a/3rdparty/assimp/code/Subdivision.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a helper class to evaluate subdivision surfaces.*/
-#ifndef AI_SUBDISIVION_H_INC
-#define AI_SUBDISIVION_H_INC
-namespace Assimp {
-
-// ------------------------------------------------------------------------------
-/** Helper class to evaluate subdivision surfaces. Different algorithms
- * are provided for choice. */
-// ------------------------------------------------------------------------------
-class ASSIMP_API Subdivider
-{
-public:
-
- /** Enumerates all supported subvidision algorithms */
- enum Algorithm {
- CATMULL_CLARKE = 0x1
- };
-
-public:
-
- virtual ~Subdivider() {
- }
-
-public:
-
- // ---------------------------------------------------------------
- /** Create a subdivider of a specific type
- *
- * @param algo Algorithm to be used for subdivision
- * @return Subdivider instance. */
- static Subdivider* Create (Algorithm algo);
-
- // ---------------------------------------------------------------
- /** Subdivide a mesh using the selected algorithm
- *
- * @param mesh First mesh to be subdivided. Must be in verbose
- * format.
- * @param out Receives the output mesh, allocated by me.
- * @param num Number of subdivisions to perform.
- * @param discard_input If true is passed, the input mesh is
- * deleted after the subdivision is complete. This can
- * improve performance because it allows the optimization
- * to reuse the existing mesh for intermediate results.
- * @pre out!=mesh*/
- virtual void Subdivide (const aiMesh* mesh,
- aiMesh*& out, unsigned int num,
- bool discard_input = false) = 0;
-
- // ---------------------------------------------------------------
- /** Subdivide multiple meshes using the selected algorithm. This
- * avoids erroneous smoothing on objects consisting of multiple
- * per-material meshes. Usually, most 3d modellers smooth on a
- * per-object base, regardless the materials assigned to the
- * meshes.
- *
- * @param smesh Array of meshes to be subdivided. Must be in
- * verbose format.
- * @param nmesh Number of meshes in smesh.
- * @param out Receives the output meshes. The array must be
- * sufficiently large (at least @c nmesh elements) and may not
- * overlap the input array. Output meshes map one-to-one to
- * their corresponding input meshes. The meshes are allocated
- * by the function.
- * @param discard_input If true is passed, input meshes are
- * deleted after the subdivision is complete. This can
- * improve performance because it allows the optimization
- * of reusing existing meshes for intermediate results.
- * @param num Number of subdivisions to perform.
- * @pre nmesh != 0, smesh and out may not overlap*/
- virtual void Subdivide (
- const aiMesh* const * smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num,
- bool discard_input = false) = 0;
-
-private:
-};
-
-} // end namespace Assimp
-
-
-#endif // !! AI_SUBDISIVION_H_INC
-
diff --git a/3rdparty/assimp/code/TargetAnimation.cpp b/3rdparty/assimp/code/TargetAnimation.cpp
deleted file mode 100644
index cdb350ff..00000000
--- a/3rdparty/assimp/code/TargetAnimation.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#include "AssimpPCH.h"
-#include "TargetAnimation.h"
-#include <algorithm>
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-KeyIterator::KeyIterator(const std::vector<aiVectorKey>* _objPos,
- const std::vector<aiVectorKey>* _targetObjPos,
- const aiVector3D* defaultObjectPos /*= NULL*/,
- const aiVector3D* defaultTargetPos /*= NULL*/)
-
- : reachedEnd (false)
- , curTime (-1.)
- , objPos (_objPos)
- , targetObjPos (_targetObjPos)
- , nextObjPos (0)
- , nextTargetObjPos(0)
-{
- // Generate default transformation tracks if necessary
- if (!objPos || objPos->empty())
- {
- defaultObjPos.resize(1);
- defaultObjPos.front().mTime = 10e10;
-
- if (defaultObjectPos)
- defaultObjPos.front().mValue = *defaultObjectPos;
-
- objPos = & defaultObjPos;
- }
- if (!targetObjPos || targetObjPos->empty())
- {
- defaultTargetObjPos.resize(1);
- defaultTargetObjPos.front().mTime = 10e10;
-
- if (defaultTargetPos)
- defaultTargetObjPos.front().mValue = *defaultTargetPos;
-
- targetObjPos = & defaultTargetObjPos;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline T Interpolate(const T& one, const T& two, float val)
-{
- return one + (two-one)*val;
-}
-
-// ------------------------------------------------------------------------------------------------
-void KeyIterator::operator ++()
-{
- // If we are already at the end of all keyframes, return
- if (reachedEnd) {
- return;
- }
-
- // Now search in all arrays for the time value closest
- // to our current position on the time line
- double d0,d1;
-
- d0 = objPos->at ( std::min<unsigned int> ( nextObjPos, objPos->size()-1) ).mTime;
- d1 = targetObjPos->at( std::min<unsigned int> ( nextTargetObjPos, targetObjPos->size()-1) ).mTime;
-
- // Easiest case - all are identical. In this
- // case we don't need to interpolate so we can
- // return earlier
- if ( d0 == d1 )
- {
- curTime = d0;
- curPosition = objPos->at(nextObjPos).mValue;
- curTargetPosition = targetObjPos->at(nextTargetObjPos).mValue;
-
- // increment counters
- if (objPos->size() != nextObjPos-1)
- ++nextObjPos;
-
- if (targetObjPos->size() != nextTargetObjPos-1)
- ++nextTargetObjPos;
- }
-
- // An object position key is closest to us
- else if (d0 < d1)
- {
- curTime = d0;
-
- // interpolate the other
- if (1 == targetObjPos->size() || !nextTargetObjPos) {
- curTargetPosition = targetObjPos->at(0).mValue;
- }
- else
- {
- const aiVectorKey& last = targetObjPos->at(nextTargetObjPos);
- const aiVectorKey& first = targetObjPos->at(nextTargetObjPos-1);
-
- curTargetPosition = Interpolate(first.mValue, last.mValue, (float) (
- (curTime-first.mTime) / (last.mTime-first.mTime) ));
- }
-
- if (objPos->size() != nextObjPos-1)
- ++nextObjPos;
- }
- // A target position key is closest to us
- else
- {
- curTime = d1;
-
- // interpolate the other
- if (1 == objPos->size() || !nextObjPos) {
- curPosition = objPos->at(0).mValue;
- }
- else
- {
- const aiVectorKey& last = objPos->at(nextObjPos);
- const aiVectorKey& first = objPos->at(nextObjPos-1);
-
- curPosition = Interpolate(first.mValue, last.mValue, (float) (
- (curTime-first.mTime) / (last.mTime-first.mTime)));
- }
-
- if (targetObjPos->size() != nextTargetObjPos-1)
- ++nextTargetObjPos;
- }
-
- if (nextObjPos >= objPos->size()-1 &&
- nextTargetObjPos >= targetObjPos->size()-1)
- {
- // We reached the very last keyframe
- reachedEnd = true;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetTargetAnimationChannel (
- const std::vector<aiVectorKey>* _targetPositions)
-{
- ai_assert(NULL != _targetPositions);
- targetPositions = _targetPositions;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetMainAnimationChannel (
- const std::vector<aiVectorKey>* _objectPositions)
-{
- ai_assert(NULL != _objectPositions);
- objectPositions = _objectPositions;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetFixedMainAnimationChannel(
- const aiVector3D& fixed)
-{
- objectPositions = NULL; // just to avoid confusion
- fixedMain = fixed;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack)
-{
- ai_assert(NULL != targetPositions && NULL != distanceTrack);
-
- // TODO: in most cases we won't need the extra array
- std::vector<aiVectorKey> real;
-
- std::vector<aiVectorKey>* fill = (distanceTrack == objectPositions ? &real : distanceTrack);
- fill->reserve(std::max( objectPositions->size(), targetPositions->size() ));
-
- // Iterate through all object keys and interpolate their values if necessary.
- // Then get the corresponding target position, compute the difference
- // vector between object and target position. Then compute a rotation matrix
- // that rotates the base vector of the object coordinate system at that time
- // to match the diff vector.
-
- KeyIterator iter(objectPositions,targetPositions,&fixedMain);
- for (;!iter.Finished();++iter)
- {
- const aiVector3D& position = iter.GetCurPosition();
- const aiVector3D& tposition = iter.GetCurTargetPosition();
-
- // diff vector
- aiVector3D diff = tposition - position;
- float f = diff.Length();
-
- // output distance vector
- if (f)
- {
- fill->push_back(aiVectorKey());
- aiVectorKey& v = fill->back();
- v.mTime = iter.GetCurTime();
- v.mValue = diff;
-
- diff /= f;
- }
- else
- {
- // FIXME: handle this
- }
-
- // diff is now the vector in which our camera is pointing
- }
-
- if (real.size()) {
- *distanceTrack = real;
- }
-}
diff --git a/3rdparty/assimp/code/TargetAnimation.h b/3rdparty/assimp/code/TargetAnimation.h
deleted file mode 100644
index 049946b3..00000000
--- a/3rdparty/assimp/code/TargetAnimation.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a helper class for the ASE and 3DS loaders to
- help them compute camera and spot light animation channels */
-#ifndef AI_TARGET_ANIMATION_H_INC
-#define AI_TARGET_ANIMATION_H_INC
-
-
-namespace Assimp {
-
-
-
-// ---------------------------------------------------------------------------
-/** Helper class to iterate through all keys in an animation channel.
- *
- * Missing tracks are interpolated. This is a helper class for
- * TargetAnimationHelper, but it can be freely used for other purposes.
-*/
-class ASSIMP_API KeyIterator
-{
-public:
-
-
- // ------------------------------------------------------------------
- /** Constructs a new key iterator
- *
- * @param _objPos Object position track. May be NULL.
- * @param _targetObjPos Target object position track. May be NULL.
- * @param defaultObjectPos Default object position to be used if
- * no animated track is available. May be NULL.
- * @param defaultTargetPos Default target position to be used if
- * no animated track is available. May be NULL.
- */
- KeyIterator(const std::vector<aiVectorKey>* _objPos,
- const std::vector<aiVectorKey>* _targetObjPos,
- const aiVector3D* defaultObjectPos = NULL,
- const aiVector3D* defaultTargetPos = NULL);
-
- // ------------------------------------------------------------------
- /** Returns true if all keys have been processed
- */
- bool Finished() const
- {return reachedEnd;}
-
- // ------------------------------------------------------------------
- /** Increment the iterator
- */
- void operator++();
- inline void operator++(int)
- {return ++(*this);}
-
-
-
- // ------------------------------------------------------------------
- /** Getters to retrieve the current state of the iterator
- */
- inline const aiVector3D& GetCurPosition() const
- {return curPosition;}
-
- inline const aiVector3D& GetCurTargetPosition() const
- {return curTargetPosition;}
-
- inline double GetCurTime() const
- {return curTime;}
-
-private:
-
- //! Did we reach the end?
- bool reachedEnd;
-
- //! Represents the current position of the iterator
- aiVector3D curPosition, curTargetPosition;
-
- double curTime;
-
- //! Input tracks and the next key to process
- const std::vector<aiVectorKey>* objPos,*targetObjPos;
-
- unsigned int nextObjPos, nextTargetObjPos;
- std::vector<aiVectorKey> defaultObjPos,defaultTargetObjPos;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper class for the 3DS and ASE loaders to compute camera and spot light
- * animations.
- *
- * 3DS and ASE store the differently to Assimp - there is an animation
- * channel for the camera/spot light itself and a separate position
- * animation channels specifying the position of the camera/spot light
- * look-at target */
-class ASSIMP_API TargetAnimationHelper
-{
-public:
-
- TargetAnimationHelper()
- : targetPositions (NULL)
- , objectPositions (NULL)
- {}
-
-
- // ------------------------------------------------------------------
- /** Sets the target animation channel
- *
- * This channel specifies the position of the camera/spot light
- * target at a specific position.
- *
- * @param targetPositions Translation channel*/
- void SetTargetAnimationChannel (const
- std::vector<aiVectorKey>* targetPositions);
-
-
- // ------------------------------------------------------------------
- /** Sets the main animation channel
- *
- * @param objectPositions Translation channel */
- void SetMainAnimationChannel ( const
- std::vector<aiVectorKey>* objectPositions);
-
- // ------------------------------------------------------------------
- /** Sets the main animation channel to a fixed value
- *
- * @param fixed Fixed value for the main animation channel*/
- void SetFixedMainAnimationChannel(const aiVector3D& fixed);
-
-
- // ------------------------------------------------------------------
- /** Computes final animation channels
- * @param distanceTrack Receive camera translation keys ... != NULL. */
- void Process( std::vector<aiVectorKey>* distanceTrack );
-
-
-private:
-
- const std::vector<aiVectorKey>* targetPositions,*objectPositions;
- aiVector3D fixedMain;
-};
-
-
-} // ! end namespace Assimp
-
-#endif // include guard
diff --git a/3rdparty/assimp/code/TerragenLoader.cpp b/3rdparty/assimp/code/TerragenLoader.cpp
deleted file mode 100644
index 6813c0e4..00000000
--- a/3rdparty/assimp/code/TerragenLoader.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the Terragen importer class */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-#include "TerragenLoader.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TerragenImporter::TerragenImporter()
-: configComputeUVs (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TerragenImporter::~TerragenImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- std::string extension = GetExtension(pFile);
-
- if ( extension == "ter")
- return true;
-
- if ( !extension.length() || checkSig) {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"terragen"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-void TerragenImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("ter");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void TerragenImporter::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_IMPORT_TER_MAKE_UVS
- configComputeUVs = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,0) );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void TerragenImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- IOStream* file = pIOHandler->Open( pFile, "rb");
-
- // Check whether we can read from the file
- if ( file == NULL)
- throw DeadlyImportError( "Failed to open TERRAGEN TERRAIN file " + pFile + ".");
-
- // Construct a stream reader to read all data in the correct endianess
- StreamReaderLE reader(file);
- if (reader.GetRemainingSize() < 16)
- throw DeadlyImportError( "TER: file is too small" );
-
- // Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
- if (::strncmp((const char*)reader.GetPtr(),AI_TERR_BASE_STRING,8))
- throw DeadlyImportError( "TER: Magic string \'TERRAGEN\' not found" );
-
- if (::strncmp((const char*)reader.GetPtr()+8,AI_TERR_TERRAIN_STRING,8))
- throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
-
- unsigned int x = 0,y = 0,mode = 0;
-
- aiNode* root = pScene->mRootNode = new aiNode();
- root->mName.Set("<TERRAGEN.TERRAIN>");
-
- // Default scaling is 30
- root->mTransformation.a1 = root->mTransformation.b2 = root->mTransformation.c3 = 30.f;
-
- // Now read all chunks until we're finished or an EOF marker is encountered
- reader.IncPtr(16);
- while (reader.GetRemainingSize() >= 4)
- {
- const char* head = (const char*)reader.GetPtr();
- reader.IncPtr(4);
-
- // EOF, break in every case
- if (!::strncmp(head,AI_TERR_EOF_STRING,4))
- break;
-
- // Number of x-data points
- if (!::strncmp(head,AI_TERR_CHUNK_XPTS,4))
- {
- x = (uint16_t)reader.GetI2();
- }
- // Number of y-data points
- else if (!::strncmp(head,AI_TERR_CHUNK_YPTS,4))
- {
- y = (uint16_t)reader.GetI2();
- }
- // Squared terrains width-1.
- else if (!::strncmp(head,AI_TERR_CHUNK_SIZE,4))
- {
- x = y = (uint16_t)reader.GetI2()+1;
- }
- // terrain scaling
- else if (!::strncmp(head,AI_TERR_CHUNK_SCAL,4))
- {
- root->mTransformation.a1 = reader.GetF4();
- root->mTransformation.b2 = reader.GetF4();
- root->mTransformation.c3 = reader.GetF4();
- }
- // mapping == 1: earth radius
- else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
- {
- reader.GetF4();
- }
- // mapping mode
- else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
- {
- mode = reader.GetI1();
- if (0 != mode)
- DefaultLogger::get()->error("TER: Unsupported mapping mode, a flat terrain is returned");
- }
- // actual terrain data
- else if (!::strncmp(head,AI_TERR_CHUNK_ALTW,4))
- {
- float hscale = (float)reader.GetI2() / 65536;
- float bheight = (float)reader.GetI2();
-
- if (!hscale)hscale = 1;
-
- // Ensure we have enough data
- if (reader.GetRemainingSize() < x*y*2)
- throw DeadlyImportError("TER: ALTW chunk is too small");
-
- if (x <= 1 || y <= 1)
- throw DeadlyImportError("TER: Invalid terrain size");
-
- // Allocate the output mesh
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = 1];
- aiMesh* m = pScene->mMeshes[0] = new aiMesh();
-
- // We return quads
- aiFace* f = m->mFaces = new aiFace[m->mNumFaces = (x-1)*(y-1)];
- aiVector3D* pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces*4];
-
- aiVector3D *uv( NULL );
- float step_y( 0.0f ), step_x( 0.0f );
- if (configComputeUVs) {
- uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
- step_y = 1.f/y;
- step_x = 1.f/x;
- }
- const int16_t* data = (const int16_t*)reader.GetPtr();
-
- for (unsigned int yy = 0, t = 0; yy < y-1;++yy) {
- for (unsigned int xx = 0; xx < x-1;++xx,++f) {
-
- // make verts
- const float fy = (float)yy, fx = (float)xx;
- register unsigned tmp,tmp2;
- *pv++ = aiVector3D(fx,fy, (float)data[(tmp2=x*yy) + xx] * hscale + bheight);
- *pv++ = aiVector3D(fx,fy+1, (float)data[(tmp=x*(yy+1)) + xx] * hscale + bheight);
- *pv++ = aiVector3D(fx+1,fy+1,(float)data[tmp + xx+1] * hscale + bheight);
- *pv++ = aiVector3D(fx+1,fy, (float)data[tmp2 + xx+1] * hscale + bheight);
-
- // also make texture coordinates, if necessary
- if (configComputeUVs) {
- *uv++ = aiVector3D( step_x*xx, step_y*yy, 0.f );
- *uv++ = aiVector3D( step_x*xx, step_y*(yy+1), 0.f );
- *uv++ = aiVector3D( step_x*(xx+1), step_y*(yy+1), 0.f );
- *uv++ = aiVector3D( step_x*(xx+1), step_y*yy, 0.f );
- }
-
- // make indices
- f->mIndices = new unsigned int[f->mNumIndices = 4];
- for (unsigned int i = 0; i < 4;++i)
- f->mIndices[i] = t++;
- }
- }
-
- // Add the mesh to the root node
- root->mMeshes = new unsigned int[root->mNumMeshes = 1];
- root->mMeshes[0] = 0;
- }
-
- // Get to the next chunk (4 byte aligned)
- unsigned dtt;
- if ((dtt = reader.GetCurrentPos() & 0x3))
- reader.IncPtr(4-dtt);
- }
-
- // Check whether we have a mesh now
- if (pScene->mNumMeshes != 1)
- throw DeadlyImportError("TER: Unable to load terrain");
-
- // Set the AI_SCENE_FLAGS_TERRAIN bit
- pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
-}
-
-#endif // !! ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
diff --git a/3rdparty/assimp/code/TerragenLoader.h b/3rdparty/assimp/code/TerragenLoader.h
deleted file mode 100644
index ddcc2bfc..00000000
--- a/3rdparty/assimp/code/TerragenLoader.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file TerragenLoader.h
- * @brief Declaration of the .ter importer class.
- */
-#ifndef INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
-#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
-
-#include "BaseImporter.h"
-namespace Assimp {
-
-// Magic strings
-#define AI_TERR_BASE_STRING "TERRAGEN"
-#define AI_TERR_TERRAIN_STRING "TERRAIN "
-#define AI_TERR_EOF_STRING "EOF "
-
-// Chunka
-#define AI_TERR_CHUNK_XPTS "XPTS"
-#define AI_TERR_CHUNK_YPTS "YPTS"
-#define AI_TERR_CHUNK_SIZE "SIZE"
-#define AI_TERR_CHUNK_SCAL "SCAL"
-#define AI_TERR_CHUNK_CRAD "CRAD"
-#define AI_TERR_CHUNK_CRVM "CRVM"
-#define AI_TERR_CHUNK_ALTW "ALTW"
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load Terragen (0.9) terrain files.
- *
- * The loader is basing on the information found here:
- * http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
-*/
-class TerragenImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- TerragenImporter();
-
- /** Destructor, private as well */
- ~TerragenImporter();
-
-public:
-
- // -------------------------------------------------------------------
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-private:
-
- bool configComputeUVs;
-
-}; //! class TerragenImporter
-
-} // end of namespace Assimp
-
-#endif // AI_AC3DIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/TextureTransform.cpp b/3rdparty/assimp/code/TextureTransform.cpp
deleted file mode 100644
index 597b34cb..00000000
--- a/3rdparty/assimp/code/TextureTransform.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file A helper class that processes texture transformations */
-
-
-#include "AssimpPCH.h"
-#include "TextureTransform.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TextureTransformStep::TextureTransformStep()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TextureTransformStep::~TextureTransformStep()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool TextureTransformStep::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_TransformUVCoords) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void TextureTransformStep::SetupProperties(const Importer* pImp)
-{
- configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
-}
-
-// ------------------------------------------------------------------------------------------------
-void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
-{
- /* This function tries to simplify the input UV transformation.
- * That's very important as it allows us to reduce the number
- * of output UV channels. The oder in which the transformations
- * are applied is - as always - scaling, rotation, translation.
- */
-
- char szTemp[512];
- int rounded = 0;
-
-
- /* Optimize the rotation angle. That's slightly difficult as
- * we have an inprecise floating-point number (when comparing
- * UV transformations we'll take that into account by using
- * an epsilon of 5 degrees). If there is a rotation value, we can't
- * perform any further optimizations.
- */
- if (info.mRotation)
- {
- float out = info.mRotation;
- if ((rounded = (int)(info.mRotation / (float)AI_MATH_TWO_PI)))
- {
- out -= rounded*(float)AI_MATH_PI;
-
- sprintf(szTemp,"Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
- DefaultLogger::get()->info(szTemp);
- }
-
- // Next step - convert negative rotation angles to positives
- if (out < 0.f)
- out = (float)AI_MATH_TWO_PI * 2 + out;
-
- info.mRotation = out;
- return;
- }
-
-
- /* Optimize UV translation in the U direction. To determine whether
- * or not we can optimize we need to look at the requested mapping
- * type (e.g. if mirroring is active there IS a difference between
- * offset 2 and 3)
- */
- if ((rounded = (int)info.mTranslation.x)) {
- float out;
- szTemp[0] = 0;
- if (aiTextureMapMode_Wrap == info.mapU) {
- // Wrap - simple take the fraction of the field
- out = info.mTranslation.x-(float)rounded;
- sprintf(szTemp,"[w] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
- }
- else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded) {
- // Mirror
- if (rounded % 2)
- rounded--;
- out = info.mTranslation.x-(float)rounded;
-
- sprintf(szTemp,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
- }
- else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU) {
- // Clamp - translations beyond 1,1 are senseless
- sprintf(szTemp,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);
-
- out = 1.f;
- }
- if (szTemp[0]) {
- DefaultLogger::get()->info(szTemp);
- info.mTranslation.x = out;
- }
- }
-
- /* Optimize UV translation in the V direction. To determine whether
- * or not we can optimize we need to look at the requested mapping
- * type (e.g. if mirroring is active there IS a difference between
- * offset 2 and 3)
- */
- if ((rounded = (int)info.mTranslation.y)) {
- float out;
- szTemp[0] = 0;
- if (aiTextureMapMode_Wrap == info.mapV) {
- // Wrap - simple take the fraction of the field
- out = info.mTranslation.y-(float)rounded;
- sprintf(szTemp,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
- }
- else if (aiTextureMapMode_Mirror == info.mapV && 1 != rounded) {
- // Mirror
- if (rounded % 2)
- rounded--;
- out = info.mTranslation.x-(float)rounded;
-
- sprintf(szTemp,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
- }
- else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV) {
- // Clamp - translations beyond 1,1 are senseless
- sprintf(szTemp,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);
-
- out = 1.f;
- }
- if (szTemp[0]) {
- DefaultLogger::get()->info(szTemp);
- info.mTranslation.y = out;
- }
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
-{
- // Don't set if == 0 && wasn't set before
- for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
- const TTUpdateInfo& info = *it;
-
- if (info.directShortcut)
- *info.directShortcut = n;
- else if (!n)
- {
- info.mat->AddProperty<int>((int*)&n,1,AI_MATKEY_UVWSRC(info.semantic,info.index));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline const char* MappingModeToChar(aiTextureMapMode map)
-{
- if (aiTextureMapMode_Wrap == map)
- return "-w";
-
- if (aiTextureMapMode_Mirror == map)
- return "-m";
-
- return "-c";
-}
-
-// ------------------------------------------------------------------------------------------------
-void TextureTransformStep::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("TransformUVCoordsProcess begin");
-
-
- /* We build a per-mesh list of texture transformations we'll need
- * to apply. To achieve this, we iterate through all materials,
- * find all textures and get their transformations and UV indices.
- * Then we search for all meshes using this material.
- */
- typedef std::list<STransformVecInfo> MeshTrafoList;
- std::vector<MeshTrafoList> meshLists(pScene->mNumMeshes);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
-
- aiMaterial* mat = pScene->mMaterials[i];
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
-
- aiMaterialProperty* prop = mat->mProperties[a];
- if (!::strcmp( prop->mKey.data, "$tex.file")) {
- STransformVecInfo info;
-
- // Setup a shortcut structure to allow for a fast updating
- // of the UV index later
- TTUpdateInfo update;
- update.mat = (MaterialHelper*) mat;
- update.semantic = prop->mSemantic;
- update.index = prop->mIndex;
-
- // Get textured properties and transform
- for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
- {
- aiMaterialProperty* prop2 = mat->mProperties[a2];
- if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
- continue;
-
- if ( !::strcmp( prop2->mKey.data, "$tex.uvwsrc"))
- {
- info.uvIndex = *((int*)prop2->mData);
-
- // Store a direct pointer for later use
- update.directShortcut = (unsigned int*) prop2->mData;
- }
-
- else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodeu"))
- info.mapU = *((aiTextureMapMode*)prop2->mData);
-
- else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodev"))
- info.mapV = *((aiTextureMapMode*)prop2->mData);
-
- else if ( !::strcmp( prop2->mKey.data, "$tex.uvtrafo"))
- {
- // ValidateDS should check this
- ai_assert(prop2->mDataLength >= 20);
- ::memcpy(&info.mTranslation.x,prop2->mData,sizeof(float)*5);
- delete[] prop2->mData;
-
- // Directly remove this property from the list
- mat->mNumProperties--;
- for (unsigned int a3 = a2; a3 < mat->mNumProperties;++a3)
- mat->mProperties[a3] = mat->mProperties[a3+1];
-
- // Warn: could be an underflow, but nevertheless it should work
- --a2;
- }
- }
-
- // Find out which transformations are to be evaluated
- if (!(configFlags & AI_UVTRAFO_ROTATION))
- info.mRotation = 0.f;
-
- if (!(configFlags & AI_UVTRAFO_SCALING))
- info.mScaling = aiVector2D(1.f,1.f);
-
- if (!(configFlags & AI_UVTRAFO_TRANSLATION))
- info.mTranslation = aiVector2D(0.f,0.f);
-
- // Do some preprocessing
- PreProcessUVTransform(info);
- info.uvIndex = std::min(info.uvIndex,AI_MAX_NUMBER_OF_TEXTURECOORDS -1u);
-
- // Find out whether this material is used by more than
- // one mesh. This will make our task much, much more difficult!
- unsigned int cnt = 0;
- for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
- if (pScene->mMeshes[n]->mMaterialIndex == i)
- ++cnt;
- }
-
- if (!cnt)
- continue;
- else if (1 != cnt) {
- // This material is referenced by more than one mesh!
- // So we need to make sure the UV index for the texture
- // is identical for each of it ...
- info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
- }
-
- // Get all coresponding meshes
- for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
- aiMesh* mesh = pScene->mMeshes[n];
- if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
- continue;
-
- unsigned int uv = info.uvIndex;
- if (!mesh->mTextureCoords[uv]) {
- // If the requested UV index is not available, take the first one instead.
- uv = 0;
- }
-
- if (mesh->mNumUVComponents[info.uvIndex] >= 3){
- DefaultLogger::get()->warn("UV transformations on 3D mapping channels are not supported");
- continue;
- }
-
- MeshTrafoList::iterator it;
-
- // Check whether we have this transform setup already
- for (it = meshLists[n].begin();it != meshLists[n].end(); ++it) {
-
- if ((*it) == info && (*it).uvIndex == uv) {
- (*it).updateList.push_back(update);
- break;
- }
- }
-
- if (it == meshLists[n].end()) {
- meshLists[n].push_back(info);
- meshLists[n].back().uvIndex = uv;
- meshLists[n].back().updateList.push_back(update);
- }
- }
- }
- }
- }
-
- char buffer[1024]; // should be sufficiently large
- unsigned int outChannels = 0, inChannels = 0, transformedChannels = 0;
-
- // Now process all meshes. Important: we don't remove unreferenced UV channels.
- // This is a job for the RemoveUnreferencedData-Step.
- for (unsigned int q = 0; q < pScene->mNumMeshes;++q) {
-
- aiMesh* mesh = pScene->mMeshes[q];
- MeshTrafoList& trafo = meshLists[q];
-
- inChannels += mesh->GetNumUVChannels();
-
- if (!mesh->mTextureCoords[0] || trafo.empty() || (trafo.size() == 1 && trafo.begin()->IsUntransformed())) {
- outChannels += mesh->GetNumUVChannels();
- continue;
- }
-
- // Move untransformed UV channels to the first position in the list ....
- // except if we need a new locked index which should be as small as possible
- bool veto = false, need = false;
- unsigned int cnt = 0;
- unsigned int untransformed = 0;
-
- MeshTrafoList::iterator it,it2;
- for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
-
- if (!(*it).IsUntransformed()) {
- need = true;
- }
-
- if ((*it).lockedPos == AI_TT_UV_IDX_LOCK_TBD) {
- // Lock this index and make sure it won't be changed
- (*it).lockedPos = cnt;
- veto = true;
- continue;
- }
-
- if (!veto && it != trafo.begin() && (*it).IsUntransformed()) {
- for (it2 = trafo.begin();it2 != it; ++it2) {
- if (!(*it2).IsUntransformed())
- break;
- }
- trafo.insert(it2,*it);
- trafo.erase(it);
- break;
- }
- }
- if (!need)
- continue;
-
- // Find all that are not at their 'locked' position and move them to it.
- // Conflicts are possible but quite unlikely.
- cnt = 0;
- for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
- if ((*it).lockedPos != AI_TT_UV_IDX_LOCK_NONE && (*it).lockedPos != cnt) {
- it2 = trafo.begin();unsigned int t = 0;
- while (t != (*it).lockedPos)
- ++it2;
-
- if ((*it2).lockedPos != AI_TT_UV_IDX_LOCK_NONE) {
- DefaultLogger::get()->error("Channel mismatch, can't compute all transformations properly [design bug]");
- continue;
- }
-
- std::swap(*it2,*it);
- if ((*it).lockedPos == untransformed)
- untransformed = cnt;
- }
- }
-
- // ... and add dummies for all unreferenced channels
- // at the end of the list
- bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
- ref[n] = (!mesh->mTextureCoords[n] ? true : false);
-
- for (it = trafo.begin();it != trafo.end(); ++it)
- ref[(*it).uvIndex] = true;
-
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
- if (ref[n])
- continue;
- trafo.push_back(STransformVecInfo());
- trafo.back().uvIndex = n;
- }
-
- // Then check whether this list breaks the channel limit.
- // The unimportant ones are at the end of the list, so
- // it shouldn't be too worse if we remove them.
- unsigned int size = (unsigned int)trafo.size();
- if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-
- if (!DefaultLogger::isNullLogger()) {
- ::sprintf(buffer,"%u UV channels required but just %u available",
- static_cast<unsigned int>(trafo.size()),AI_MAX_NUMBER_OF_TEXTURECOORDS);
-
- DefaultLogger::get()->error(buffer);
- }
- size = AI_MAX_NUMBER_OF_TEXTURECOORDS;
- }
-
-
- aiVector3D* old[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
- old[n] = mesh->mTextureCoords[n];
-
- // Now continue and generate the output channels. Channels
- // that we're not going to need later can be overridden.
- it = trafo.begin();
- for (unsigned int n = 0; n < trafo.size();++n,++it) {
-
- if (n >= size) {
- // Try to use an untransformed channel for all channels we threw over board
- UpdateUVIndex((*it).updateList,untransformed);
- continue;
- }
-
- outChannels++;
-
- // Write to the log
- if (!DefaultLogger::isNullLogger()) {
- sprintf(buffer,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
- q,n,
- (*it).mTranslation.x,
- (*it).mTranslation.y,
- (*it).mScaling.x,
- (*it).mScaling.y,
- AI_RAD_TO_DEG( (*it).mRotation),
- MappingModeToChar ((*it).mapU),
- MappingModeToChar ((*it).mapV));
-
- DefaultLogger::get()->info(buffer);
- }
-
- // Check whether we need a new buffer here
- if (mesh->mTextureCoords[n]) {
-
- it2 = it;++it2;
- for (unsigned int m = n+1; m < size;++m, ++it2) {
-
- if ((*it2).uvIndex == n){
- it2 = trafo.begin();
- break;
- }
- }
- if (it2 == trafo.begin()){
- mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
- }
- }
- else mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
-
- aiVector3D* src = old[(*it).uvIndex];
- aiVector3D* dest, *end;
- dest = mesh->mTextureCoords[n];
-
- ai_assert(NULL != src);
-
- // Copy the data to the destination array
- if (dest != src)
- ::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
-
- end = dest + mesh->mNumVertices;
-
- // Build a transformation matrix and transform all UV coords with it
- if (!(*it).IsUntransformed()) {
- const aiVector2D& trl = (*it).mTranslation;
- const aiVector2D& scl = (*it).mScaling;
-
- // fixme: simplify ..
- ++transformedChannels;
- aiMatrix3x3 matrix;
-
- aiMatrix3x3 m2,m3,m4,m5;
-
- m4.a1 = scl.x;
- m4.b2 = scl.y;
-
- m2.a3 = m2.b3 = 0.5f;
- m3.a3 = m3.b3 = -0.5f;
-
- if ((*it).mRotation > AI_TT_ROTATION_EPSILON )
- aiMatrix3x3::RotationZ((*it).mRotation,matrix);
-
- m5.a3 += trl.x; m5.b3 += trl.y;
- matrix = m2 * m4 * matrix * m3 * m5;
-
- for (src = dest; src != end; ++src) { /* manual homogenious divide */
- src->z = 1.f;
- *src = matrix * *src;
- src->x /= src->z;
- src->y /= src->z;
- src->z = 0.f;
- }
- }
-
- // Update all UV indices
- UpdateUVIndex((*it).updateList,n);
- }
- }
-
- // Print some detailled statistics into the log
- if (!DefaultLogger::isNullLogger()) {
-
- if (transformedChannels) {
- ::sprintf(buffer,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
- outChannels,inChannels,transformedChannels);
-
- DefaultLogger::get()->info(buffer);
- }
- else DefaultLogger::get()->debug("TransformUVCoordsProcess finished");
- }
-}
-
-
diff --git a/3rdparty/assimp/code/TextureTransform.h b/3rdparty/assimp/code/TextureTransform.h
deleted file mode 100644
index a9d711f3..00000000
--- a/3rdparty/assimp/code/TextureTransform.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Definition of a helper step that processes texture transformations */
-#ifndef AI_TEXTURE_TRANSFORM_H_INCLUDED
-#define AI_TEXTURE_TRANSFORM_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-
-struct aiNode;
-
-namespace Assimp {
-
-#define AI_TT_UV_IDX_LOCK_TBD 0xffffffff
-#define AI_TT_UV_IDX_LOCK_NONE 0xeeeeeeee
-
-
-#define AI_TT_ROTATION_EPSILON ((float)AI_DEG_TO_RAD(0.5))
-
-// ---------------------------------------------------------------------------
-/** Small helper structure representing a shortcut into the material list
- * to be able to update some values quickly.
-*/
-struct TTUpdateInfo
-{
- TTUpdateInfo() :
- directShortcut (NULL)
- , mat (NULL)
- , semantic (0)
- , index (0)
- {}
-
- //! Direct shortcut, if available
- unsigned int* directShortcut;
-
- //! Material
- MaterialHelper *mat;
-
- //! Texture type and index
- unsigned int semantic, index;
-};
-
-
-// ---------------------------------------------------------------------------
-/** Helper class representing texture coordinate transformations
-*/
-struct STransformVecInfo : public aiUVTransform
-{
-
- STransformVecInfo()
- : uvIndex (0)
- , mapU (aiTextureMapMode_Wrap)
- , mapV (aiTextureMapMode_Wrap)
- , lockedPos (AI_TT_UV_IDX_LOCK_NONE)
- {}
-
- //! Source texture coordinate index
- unsigned int uvIndex;
-
- //! Texture mapping mode in the u, v direction
- aiTextureMapMode mapU,mapV;
-
- //! Locked destination UV index
- //! AI_TT_UV_IDX_LOCK_TBD - to be determined
- //! AI_TT_UV_IDX_LOCK_NONE - none (default)
- unsigned int lockedPos;
-
- //! Update info - shortcuts into all materials
- //! that are referencing this transform setup
- std::list<TTUpdateInfo> updateList;
-
-
- // -------------------------------------------------------------------
- /** Compare two transform setups
- */
- inline bool operator== (const STransformVecInfo& other) const
- {
- // We use a small epsilon here
- const static float epsilon = 0.05f;
-
- if (fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
- fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
- {
- return false;
- }
-
- if (fabs( mScaling.x - other.mScaling.x ) > epsilon ||
- fabs( mScaling.y - other.mScaling.y ) > epsilon)
- {
- return false;
- }
-
- if (fabs( mRotation - other.mRotation) > epsilon)
- {
- return false;
- }
- return true;
- }
-
- inline bool operator!= (const STransformVecInfo& other) const
- {
- return !(*this == other);
- }
-
-
- // -------------------------------------------------------------------
- /** Returns whether this is an untransformed texture coordinate set
- */
- inline bool IsUntransformed() const
- {
- return (1.0f == mScaling.x && 1.f == mScaling.y &&
- !mTranslation.x && !mTranslation.y &&
- mRotation < AI_TT_ROTATION_EPSILON);
- }
-
- // -------------------------------------------------------------------
- /** Build a 3x3 matrix from the transformations
- */
- inline void GetMatrix(aiMatrix3x3& mOut)
- {
- mOut = aiMatrix3x3();
-
- if (1.0f != mScaling.x || 1.0f != mScaling.y)
- {
- aiMatrix3x3 mScale;
- mScale.a1 = mScaling.x;
- mScale.b2 = mScaling.y;
- mOut = mScale;
- }
- if (mRotation)
- {
- aiMatrix3x3 mRot;
- mRot.a1 = mRot.b2 = cos(mRotation);
- mRot.a2 = mRot.b1 = sin(mRotation);
- mRot.a2 = -mRot.a2;
- mOut *= mRot;
- }
- if (mTranslation.x || mTranslation.y)
- {
- aiMatrix3x3 mTrans;
- mTrans.a3 = mTranslation.x;
- mTrans.b3 = mTranslation.y;
- mOut *= mTrans;
- }
- }
-};
-
-
-// ---------------------------------------------------------------------------
-/** Helper step to compute final UV coordinate sets if there are scalings
- * or rotations in the original data read from the file.
-*/
-class ASSIMP_API TextureTransformStep : public BaseProcess
-{
-public:
-
- TextureTransformStep();
- ~TextureTransformStep();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Preprocess a specific UV transformation setup
- *
- * @param info Transformation setup to be preprocessed.
- */
- void PreProcessUVTransform(STransformVecInfo& info);
-
-private:
-
- unsigned int configFlags;
-};
-
-}
-
-#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED
diff --git a/3rdparty/assimp/code/TinyFormatter.h b/3rdparty/assimp/code/TinyFormatter.h
deleted file mode 100644
index c9e64fc5..00000000
--- a/3rdparty/assimp/code/TinyFormatter.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file TinyFormatter.h
- * @brief Utility to format log messages more easily. Introduced
- * to get rid of the boost::format dependency. Much slinker,
- * basically just extends stringstream.
- */
-#ifndef INCLUDED_TINY_FORMATTER_H
-#define INCLUDED_TINY_FORMATTER_H
-
-#include <sstream>
-
-namespace Assimp {
- namespace Formatter {
-
-// ------------------------------------------------------------------------------------------------
-/** stringstream utility. Usage:
- * @code
- * void writelog(const std::string&s);
- * void writelog(const std::wstring&s);
- * ...
- * writelog(format()<< "hi! this is a number: " << 4);
- * writelog(wformat()<< L"hi! this is a number: " << 4);
- *
- * @endcode */
-template < typename T,
- typename CharTraits = std::char_traits<T>,
- typename Allocator = std::allocator<T>
->
-class basic_formatter
-{
-
-public:
-
- typedef class std::basic_string<
- T,CharTraits,Allocator
- > string;
-
- typedef class std::basic_ostringstream<
- T,CharTraits,Allocator
- > stringstream;
-
-public:
-
- basic_formatter() {}
-
- /* Allow basic_formatter<T>'s to be used almost interchangeably
- * with std::(w)string or const (w)char* arguments because the
- * conversion c'tor is called implicitly. */
- template <typename TT>
- basic_formatter(const TT& sin) {
- underlying << sin;
- }
-
-public:
-
- operator string () const {
- return underlying.str();
- }
-
-
- /* note - this is declared const because binding temporaries does only
- * work for const references, so many function prototypes will
- * include const basic_formatter<T>& s but might still want to
- * modify the formatted string without the need for a full copy.*/
- template <typename TToken>
- const basic_formatter& operator << (const TToken& s) const {
- underlying << s;
- return *this;
- }
-
- template <typename TToken>
- basic_formatter& operator << (const TToken& s) {
- underlying << s;
- return *this;
- }
-
-
- // comma operator overloaded as well, choose your preferred way.
- template <typename TToken>
- const basic_formatter& operator, (const TToken& s) const {
- underlying << s;
- return *this;
- }
-
- template <typename TToken>
- basic_formatter& operator, (const TToken& s) {
- underlying << s;
- return *this;
- }
-
-private:
- mutable stringstream underlying;
-};
-
-
-typedef basic_formatter< char > format;
-typedef basic_formatter< wchar_t > wformat;
-
-} // ! namespace Formatter
-
-} // ! namespace Assimp
-#endif
diff --git a/3rdparty/assimp/code/TriangulateProcess.cpp b/3rdparty/assimp/code/TriangulateProcess.cpp
deleted file mode 100644
index d9899a0f..00000000
--- a/3rdparty/assimp/code/TriangulateProcess.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2009, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file TriangulateProcess.cpp
- * @brief Implementation of the post processing step to split up
- * all faces with more than three indices into triangles.
- *
- *
- * The triangulation algorithm will handle concave or convex polygons.
- * Self-intersecting or non-planar polygons are not rejected, but
- * they're probably not triangulated correctly.
- *
- * AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- * - generates vertex colors to represent the face winding order.
- * the first vertex of a polygon becomes red, the last blue.
- */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-#include "TriangulateProcess.h"
-#include "ProcessHelper.h"
-
-//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TriangulateProcess::TriangulateProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TriangulateProcess::~TriangulateProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool TriangulateProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_Triangulate) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void TriangulateProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("TriangulateProcess begin");
-
- bool bHas = false;
- for ( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if ( TriangulateMesh( pScene->mMeshes[a]))
- bHas = true;
- }
- if (bHas)DefaultLogger::get()->info ("TriangulateProcess finished. All polygons have been triangulated.");
- else DefaultLogger::get()->debug("TriangulateProcess finished. There was nothing to be done.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Test whether a point p2 is on the left side of the line formed by p0-p1
-inline bool OnLeftSideOfLine(const aiVector2D& p0, const aiVector2D& p1,const aiVector2D& p2)
-{
- return ( (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y) ) > 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Test whether a point is inside a given triangle in R2
-inline bool PointInTriangle2D(const aiVector2D& p0, const aiVector2D& p1,const aiVector2D& p2, const aiVector2D& pp)
-{
- // Point in triangle test using baryzentric coordinates
- const aiVector2D v0 = p1 - p0;
- const aiVector2D v1 = p2 - p0;
- const aiVector2D v2 = pp - p0;
-
- float dot00 = v0 * v0;
- float dot01 = v0 * v1;
- float dot02 = v0 * v2;
- float dot11 = v1 * v1;
- float dot12 = v1 * v2;
-
- const float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
- dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
- dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
- return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Triangulates the given mesh.
-bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
-{
- // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
- if (!pMesh->mPrimitiveTypes) {
- bool bNeed = false;
-
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- const aiFace& face = pMesh->mFaces[a];
-
- if ( face.mNumIndices != 3) {
- bNeed = true;
- }
- }
- if (!bNeed)
- return false;
- }
- else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
- return false;
- }
-
- // the output mesh will contain triangles, but no polys anymore
- pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
-
- // Find out how many output faces we'll get
- unsigned int numOut = 0, max_out = 0;
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- aiFace& face = pMesh->mFaces[a];
- if ( face.mNumIndices <= 3)
- numOut++;
-
- else {
- numOut += face.mNumIndices-2;
- max_out = std::max(max_out,face.mNumIndices);
- }
- }
-
- // Just another check whether aiMesh::mPrimitiveTypes is correct
- assert(numOut != pMesh->mNumFaces);
-
- aiVector3D* nor_out = NULL;
- if (!pMesh->mNormals && pMesh->mPrimitiveTypes == aiPrimitiveType_POLYGON) {
- nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- }
-
- aiFace* out = new aiFace[numOut], *curOut = out;
- std::vector<aiVector3D> temp_verts(max_out+2); /* temporary storage for vertices */
-
- // Apply vertex colors to represent the face winding?
-#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- if (!pMesh->mColors[0])
- pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
- else
- new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices];
-
- aiColor4D* clr = pMesh->mColors[0];
-#endif
-
- // use boost::scoped_array to avoid slow std::vector<bool> specialiations
- boost::scoped_array<bool> done(new bool[max_out]);
- for ( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- aiFace& face = pMesh->mFaces[a];
-
- unsigned int* idx = face.mIndices;
- int num = (int)face.mNumIndices, ear = 0, tmp, prev = num-1, next = 0, max = num;
-
- // Apply vertex colors to represent the face winding?
-#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- for (unsigned int i = 0; i < face.mNumIndices; ++i) {
- aiColor4D& c = clr[idx[i]];
- c.r = (i+1) / (float)max;
- c.b = 1.f - c.r;
- }
-#endif
-
- // if it's a simple point,line or triangle: just copy it
- if ( face.mNumIndices <= 3)
- {
- aiFace& nface = *curOut++;
- nface.mNumIndices = face.mNumIndices;
- nface.mIndices = face.mIndices;
- }
- // quadrilaterals can't have ears. trifanning will always work
- else if ( face.mNumIndices == 4) {
- aiFace& nface = *curOut++;
- nface.mNumIndices = 3;
- nface.mIndices = face.mIndices;
-
- aiFace& sface = *curOut++;
- sface.mNumIndices = 3;
- sface.mIndices = new unsigned int[3];
-
- sface.mIndices[0] = face.mIndices[0];
- sface.mIndices[1] = face.mIndices[2];
- sface.mIndices[2] = face.mIndices[3];
- }
- else
- {
- // A polygon with more than 3 vertices can be either concave or convex.
- // Usually everything we're getting is convex and we could easily
- // triangulate by trifanning. However, LightWave is probably the only
- // modeller to make extensive use of highly concave monster polygons ...
- // so we need to apply the full 'ear cutting' algorithm.
-
- // RERQUIREMENT: polygon is expected to be simple and *nearly* planar.
- // We project it onto a plane to get 2d data. Working in R3 would
- // also be possible but it's more difficult to implement.
-
- // Collect all vertices of of the polygon.
- aiVector3D* verts = pMesh->mVertices;
- for (tmp = 0; tmp < max; ++tmp) {
- temp_verts[tmp] = verts[idx[tmp]];
- }
-
- // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
- aiVector3D n;
- NewellNormal<3,3,3>(n,max,&temp_verts.front().x,&temp_verts.front().y,&temp_verts.front().z);
- if (nor_out) {
- for (tmp = 0; tmp < max; ++tmp)
- nor_out[idx[tmp]] = n;
- }
-
- // Select largest normal coordinate to ignore for projection
- const float ax = (n.x>0 ? n.x : -n.x);
- const float ay = (n.y>0 ? n.y : -n.y);
- const float az = (n.z>0 ? n.z : -n.z);
-
- unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */
- float inv = n.z;
- if (ax > ay) {
- if (ax > az) { /* no x coord. projection to yz */
- ac = 1; bc = 2;
- inv = n.x;
- }
- }
- else if (ay > az) { /* no y coord. projection to zy */
- ac = 2; bc = 0;
- inv = n.y;
- }
-
- // Swap projection axes to take the negated projection vector into account
- if (inv < 0.f) {
- std::swap(ac,bc);
- }
-
- for (tmp =0; tmp < max; ++tmp) {
- temp_verts[tmp].x = verts[idx[tmp]][ac];
- temp_verts[tmp].y = verts[idx[tmp]][bc];
- done[tmp] = false;
- }
-
- //
- // FIXME: currently this is the slow O(kn) variant with a worst case
- // complexity of O(n^2) (I think). Can be done in O(n).
- while (num > 3) {
-
- // Find the next ear of the polygon
- int num_found = 0;
- for (ear = next;;prev = ear,ear = next) {
-
- // break after we looped two times without a positive match
- for (next=ear+1;done[(next>max-1?next=0:next)];++next) {};
- if (next < ear) {
- if (++num_found == 2) {
- break;
- }
- }
- const aiVector2D* pnt1 = (const aiVector2D*)&temp_verts[ear],
- *pnt0 = (const aiVector2D*)&temp_verts[prev],
- *pnt2 = (const aiVector2D*)&temp_verts[next];
-
- // Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
- if (OnLeftSideOfLine (*pnt0,*pnt2,*pnt1)) {
- continue;
- }
-
- // and no other point may be contained in this triangle
- for ( tmp = 0; tmp < max; ++tmp) {
-
- // We need to compare the actual values because it's possible that multiple indexes in
- // the polygon are refering to the same position. concave_polygon.obj is a sample
- //
- // FIXME: Use 'epsiloned' comparisons instead? Due to numeric inaccuracies in
- // PointInTriangle() I'm guessing that it's actually possible to construct
- // input data that would cause us to end up with no ears. The problem is,
- // which epsilon? If we chose a too large value, we'd get wrong results
- const aiVector2D& vtmp = * ((aiVector2D*) &temp_verts[tmp] );
- if ( vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0,*pnt1,*pnt2,vtmp))
- break;
-
- }
- if (tmp != max) {
- continue;
- }
-
- // this vertex is an ear
- break;
- }
- if (num_found == 2) {
-
- // Due to the 'two ear theorem', every simple polygon with more than three points must
- // have 2 'ears'. Here's definitely someting wrong ... but we don't give up yet.
- //
-
- // Instead we're continuting with the standard trifanning algorithm which we'd
- // use if we had only convex polygons. That's life.
- DefaultLogger::get()->error("Failed to triangulate polygon (no ear found). Probably not a simple polygon?");
-
- curOut -= (max-num); /* undo all previous work */
- for (tmp = 0; tmp < max-2; ++tmp) {
- aiFace& nface = *curOut++;
-
- nface.mNumIndices = 3;
- if (!nface.mIndices)
- nface.mIndices = new unsigned int[3];
-
- nface.mIndices[0] = idx[0];
- nface.mIndices[1] = idx[tmp+1];
- nface.mIndices[2] = idx[tmp+2];
- }
- num = 0;
- break;
- }
-
- aiFace& nface = *curOut++;
- nface.mNumIndices = 3;
-
- if (!nface.mIndices) {
- nface.mIndices = new unsigned int[3];
- }
-
- // setup indices for the new triangle ...
- nface.mIndices[0] = idx[prev];
- nface.mIndices[1] = idx[ear];
- nface.mIndices[2] = idx[next];
-
- // exclude the ear from most further processing
- done[ear] = true;
- --num;
- }
- if (num > 0) {
- // We have three indices forming the last 'ear' remaining. Collect them.
- aiFace& nface = *curOut++;
- nface.mNumIndices = 3;
- nface.mIndices = face.mIndices;
-
- for (tmp = 0; done[tmp]; ++tmp) {};
- idx[0] = idx[tmp];
-
- for (++tmp; done[tmp]; ++tmp) {};
- idx[1] = idx[tmp];
-
- for (++tmp; done[tmp]; ++tmp) {};
- idx[2] = idx[tmp];
- }
- }
- face.mIndices = NULL; /* prevent unintended deletion of our awesome results. would be a pity */
- }
-
- // kill the old faces
- delete [] pMesh->mFaces;
-
- // ... and store the new ones
- pMesh->mFaces = out;
- pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */
- return true;
-}
-
-#endif // !! ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
diff --git a/3rdparty/assimp/code/TriangulateProcess.h b/3rdparty/assimp/code/TriangulateProcess.h
deleted file mode 100644
index 7a680e5a..00000000
--- a/3rdparty/assimp/code/TriangulateProcess.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a post processing step to triangulate all faces
- with more than three vertices.
- */
-#ifndef AI_TRIANGULATEPROCESS_H_INC
-#define AI_TRIANGULATEPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-class TriangulateProcessTest;
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The TriangulateProcess splits up all faces with more than three indices
- * into triangles. You usually want this to happen because the graphics cards
- * need their data as triangles.
- */
-class ASSIMP_API TriangulateProcess : public BaseProcess
-{
- friend class Importer;
- friend class ::TriangulateProcessTest; // grant the unit test full access to us
-
-protected:
- /** Constructor to be privately used by Importer */
- TriangulateProcess();
-
- /** Destructor, private as well */
- ~TriangulateProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
- // -------------------------------------------------------------------
- /** Triangulates the given mesh.
- * @param pMesh The mesh to triangulate.
- */
- bool TriangulateMesh( aiMesh* pMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_TRIANGULATEPROCESS_H_INC
diff --git a/3rdparty/assimp/code/UnrealLoader.cpp b/3rdparty/assimp/code/UnrealLoader.cpp
deleted file mode 100644
index 4985e7a9..00000000
--- a/3rdparty/assimp/code/UnrealLoader.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file UnrealLoader.cpp
- * @brief Implementation of the UNREAL (*.3D) importer class
- *
- * Sources:
- * http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
- */
-
-#include "AssimpPCH.h"
-
-#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-
-#include "UnrealLoader.h"
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-UnrealImporter::UnrealImporter()
-: configFrameID (0)
-, configHandleFlags (true)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-UnrealImporter::~UnrealImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"3d","uc");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-void UnrealImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("3d");
- extensions.insert("uc");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void UnrealImporter::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME,0xffffffff);
- if (0xffffffff == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
- configHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS,1));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void UnrealImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- // For any of the 3 files being passed get the three correct paths
- // First of all, determine file extension
- std::string::size_type pos = pFile.find_last_of('.');
- std::string extension = GetExtension(pFile);
-
- std::string d_path,a_path,uc_path;
- if (extension == "3d") {
- // jjjj_d.3d
- // jjjj_a.3d
- pos = pFile.find_last_of('_');
- if (std::string::npos == pos) {
- throw DeadlyImportError("UNREAL: Unexpected naming scheme");
- }
- extension = pFile.substr(0,pos);
- }
- else {
- extension = pFile.substr(0,pos);
- }
-
- // build proper paths
- d_path = extension+"_d.3d";
- a_path = extension+"_a.3d";
- uc_path = extension+".uc";
-
- DefaultLogger::get()->debug("UNREAL: data file is " + d_path);
- DefaultLogger::get()->debug("UNREAL: aniv file is " + a_path);
- DefaultLogger::get()->debug("UNREAL: uc file is " + uc_path);
-
- // and open the files ... we can't live without them
- IOStream* p = pIOHandler->Open(d_path);
- if (!p)
- throw DeadlyImportError("UNREAL: Unable to open _d file");
- StreamReaderLE d_reader(pIOHandler->Open(d_path));
-
- const uint16_t numTris = d_reader.GetI2();
- const uint16_t numVert = d_reader.GetI2();
- d_reader.IncPtr(44);
- if (!numTris || numVert < 3)
- throw DeadlyImportError("UNREAL: Invalid number of vertices/triangles");
-
- // maximum texture index
- unsigned int maxTexIdx = 0;
-
- // collect triangles
- std::vector<Unreal::Triangle> triangles(numTris);
- for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
- Unreal::Triangle& tri = *it;
-
- for (unsigned int i = 0; i < 3;++i) {
-
- tri.mVertex[i] = d_reader.GetI2();
- if (tri.mVertex[i] >= numTris) {
- DefaultLogger::get()->warn("UNREAL: vertex index out of range");
- tri.mVertex[i] = 0;
- }
- }
- tri.mType = d_reader.GetI1();
-
- // handle mesh flagss?
- if (configHandleFlags)
- tri.mType = Unreal::MF_NORMAL_OS;
- else {
- // ignore MOD and MASKED for the moment, treat them as two-sided
- if (tri.mType == Unreal::MF_NORMAL_MOD_TS || tri.mType == Unreal::MF_NORMAL_MASKED_TS)
- tri.mType = Unreal::MF_NORMAL_TS;
- }
- d_reader.IncPtr(1);
-
- for (unsigned int i = 0; i < 3;++i)
- for (unsigned int i2 = 0; i2 < 2;++i2)
- tri.mTex[i][i2] = d_reader.GetI1();
-
- tri.mTextureNum = d_reader.GetI1();
- maxTexIdx = std::max(maxTexIdx,(unsigned int)tri.mTextureNum);
- d_reader.IncPtr(1);
- }
-
- p = pIOHandler->Open(a_path);
- if (!p)
- throw DeadlyImportError("UNREAL: Unable to open _a file");
- StreamReaderLE a_reader(pIOHandler->Open(a_path));
-
- // read number of frames
- const uint32_t numFrames = a_reader.GetI2();
- if (configFrameID >= numFrames)
- throw DeadlyImportError("UNREAL: The requested frame does not exist");
-
- uint32_t st = a_reader.GetI2();
- if (st != numVert*4u)
- throw DeadlyImportError("UNREAL: Unexpected aniv file length");
-
- // skip to our frame
- a_reader.IncPtr(configFrameID *numVert*4);
-
- // collect vertices
- std::vector<aiVector3D> vertices(numVert);
- for (std::vector<aiVector3D>::iterator it = vertices.begin(), end = vertices.end(); it != end; ++it) {
- int32_t val = a_reader.GetI4();
- Unreal::DecompressVertex(*it,val);
- }
-
- // list of textures.
- std::vector< std::pair<unsigned int, std::string> > textures;
-
- // allocate the output scene
- aiNode* nd = pScene->mRootNode = new aiNode();
- nd->mName.Set("<UnrealRoot>");
-
- // we can live without the uc file if necessary
- boost::scoped_ptr<IOStream> pb (pIOHandler->Open(uc_path));
- if (pb.get()) {
-
- std::vector<char> _data;
- TextFileToBuffer(pb.get(),_data);
- const char* data = &_data[0];
-
- std::vector< std::pair< std::string,std::string > > tempTextures;
-
- // do a quick search in the UC file for some known, usually texture-related, tags
- for (;*data;++data) {
- if (TokenMatchI(data,"#exec",5)) {
- SkipSpacesAndLineEnd(&data);
-
- // #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
- if (TokenMatchI(data,"TEXTURE",7)) {
- SkipSpacesAndLineEnd(&data);
-
- if (TokenMatchI(data,"IMPORT",6)) {
- tempTextures.push_back(std::pair< std::string,std::string >());
- std::pair< std::string,std::string >& me = tempTextures.back();
- for (;!IsLineEnd(*data);++data) {
- if (!::ASSIMP_strincmp(data,"NAME=",5)) {
- const char *d = data+=5;
- for (;!IsSpaceOrNewLine(*data);++data) {};
- me.first = std::string(d,(size_t)(data-d));
- }
- else if (!::ASSIMP_strincmp(data,"FILE=",5)) {
- const char *d = data+=5;
- for (;!IsSpaceOrNewLine(*data);++data) {};
- me.second = std::string(d,(size_t)(data-d));
- }
- }
- if (!me.first.length() || !me.second.length())
- tempTextures.pop_back();
- }
- }
- // #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
- // #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
- else if (TokenMatchI(data,"MESHMAP",7)) {
- SkipSpacesAndLineEnd(&data);
-
- if (TokenMatchI(data,"SETTEXTURE",10)) {
-
- textures.push_back(std::pair<unsigned int, std::string>());
- std::pair<unsigned int, std::string>& me = textures.back();
-
- for (;!IsLineEnd(*data);++data) {
- if (!::ASSIMP_strincmp(data,"NUM=",4)) {
- data += 4;
- me.first = strtol10(data,&data);
- }
- else if (!::ASSIMP_strincmp(data,"TEXTURE=",8)) {
- data += 8;
- const char *d = data;
- for (;!IsSpaceOrNewLine(*data);++data) {};
- me.second = std::string(d,(size_t)(data-d));
-
- // try to find matching path names, doesn't care if we don't find them
- for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
- it != tempTextures.end(); ++it) {
- if ((*it).first == me.second) {
- me.second = (*it).second;
- break;
- }
- }
- }
- }
- }
- else if (TokenMatchI(data,"SCALE",5)) {
-
- for (;!IsLineEnd(*data);++data) {
- if (data[0] == 'X' && data[1] == '=') {
- data = fast_atof_move(data+2,(float&)nd->mTransformation.a1);
- }
- else if (data[0] == 'Y' && data[1] == '=') {
- data = fast_atof_move(data+2,(float&)nd->mTransformation.b2);
- }
- else if (data[0] == 'Z' && data[1] == '=') {
- data = fast_atof_move(data+2,(float&)nd->mTransformation.c3);
- }
- }
- }
- }
- }
- }
- }
- else {
- DefaultLogger::get()->error("Unable to open .uc file");
- }
-
- std::vector<Unreal::TempMat> materials;
- materials.reserve(textures.size()*2+5);
-
- // find out how many output meshes and materials we'll have and build material indices
- for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
- Unreal::Triangle& tri = *it;
- Unreal::TempMat mat(tri);
- std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
- if (nt == materials.end()) {
- // add material
- tri.matIndex = materials.size();
- mat.numFaces = 1;
- materials.push_back(mat);
-
- ++pScene->mNumMeshes;
- }
- else {
- tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
- ++nt->numFaces;
- }
- }
-
- if (!pScene->mNumMeshes) {
- throw DeadlyImportError("UNREAL: Unable to find valid mesh data");
- }
-
- // allocate meshes and bind them to the node graph
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
-
- nd->mNumMeshes = pScene->mNumMeshes;
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- aiMesh* m = pScene->mMeshes[i] = new aiMesh();
- m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- const unsigned int num = materials[i].numFaces;
- m->mFaces = new aiFace [num];
- m->mVertices = new aiVector3D [num*3];
- m->mTextureCoords[0] = new aiVector3D [num*3];
-
- nd->mMeshes[i] = i;
-
- // create materials, too
- MaterialHelper* mat = new MaterialHelper();
- pScene->mMaterials[i] = mat;
-
- // all white by default - texture rulez
- aiColor3D color(1.f,1.f,1.f);
-
- aiString s;
- ::sprintf(s.data,"mat%i_tx%i_",i,materials[i].tex);
-
- // set the two-sided flag
- if (materials[i].type == Unreal::MF_NORMAL_TS) {
- const int twosided = 1;
- mat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
- ::strcat(s.data,"ts_");
- }
- else ::strcat(s.data,"os_");
-
- // make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
- if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
- const float opac = 0.9f;
- mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
- ::strcat(s.data,"tran_");
- }
- else ::strcat(s.data,"opaq_");
-
- // a special name for the weapon attachment point
- if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
- s.length = ::sprintf(s.data,"$WeaponTag$");
- color = aiColor3D(0.f,0.f,0.f);
- }
-
- // set color and name
- mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
- s.length = ::strlen(s.data);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- // set texture, if any
- const unsigned int tex = materials[i].tex;
- for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it) {
- if ((*it).first == tex) {
- s.Set((*it).second);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- break;
- }
- }
- }
-
- // fill them.
- for (std::vector<Unreal::Triangle>::iterator it = triangles.begin(), end = triangles.end();it != end; ++it) {
- Unreal::Triangle& tri = *it;
- Unreal::TempMat mat(tri);
- std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
-
- aiMesh* mesh = pScene->mMeshes[nt-materials.begin()];
- aiFace& f = mesh->mFaces[mesh->mNumFaces++];
- f.mIndices = new unsigned int[f.mNumIndices = 3];
-
- for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
- f.mIndices[i] = mesh->mNumVertices;
-
- mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
- mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
- }
- }
-
- // convert to RH
- MakeLeftHandedProcess hero;
- hero.Execute(pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-}
-
-#endif // !! ASSIMP_BUILD_NO_3D_IMPORTER
diff --git a/3rdparty/assimp/code/UnrealLoader.h b/3rdparty/assimp/code/UnrealLoader.h
deleted file mode 100644
index 876fe83a..00000000
--- a/3rdparty/assimp/code/UnrealLoader.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file UnrealLoader.h
- * @brief Declaration of the .3d (UNREAL) importer class.
- */
-#ifndef INCLUDED_AI_3D_LOADER_H
-#define INCLUDED_AI_3D_LOADER_H
-
-#include "BaseImporter.h"
-namespace Assimp {
-namespace Unreal {
-
- /*
- 0 = Normal one-sided
- 1 = Normal two-sided
- 2 = Translucent two-sided
- 3 = Masked two-sided
- 4 = Modulation blended two-sided
- 8 = Placeholder triangle for weapon positioning (invisible)
- */
-enum MeshFlags {
- MF_NORMAL_OS = 0,
- MF_NORMAL_TS = 1,
- MF_NORMAL_TRANS_TS = 2,
- MF_NORMAL_MASKED_TS = 3,
- MF_NORMAL_MOD_TS = 4,
- MF_WEAPON_PLACEHOLDER = 8
-};
-
- // a single triangle
-struct Triangle {
- uint16_t mVertex[3]; // Vertex indices
- char mType; // James' Mesh Type
- char mColor; // Color for flat and Gourand Shaded
- unsigned char mTex[3][2]; // Texture UV coordinates
- unsigned char mTextureNum; // Source texture offset
- char mFlags; // Unreal Mesh Flags (unused)
-
- unsigned int matIndex;
-};
-
-// temporary representation for a material
-struct TempMat {
- TempMat()
- : numFaces (0)
- {}
-
- TempMat(const Triangle& in)
- : type ((Unreal::MeshFlags)in.mType)
- , tex (in.mTextureNum)
- , numFaces (0)
- {}
-
- // type of mesh
- Unreal::MeshFlags type;
-
- // index of texture
- unsigned int tex;
-
- // number of faces using us
- unsigned int numFaces;
-
- // for std::find
- bool operator == (const TempMat& o ) {
- return (tex == o.tex && type == o.type);
- }
-};
-
-struct Vertex
-{
- int32_t X : 11;
- int32_t Y : 11;
- int32_t Z : 10;
-};
-
- // UNREAL vertex compression
-inline void CompressVertex(const aiVector3D& v, uint32_t& out)
-{
- union {
- Vertex n;
- int32_t t;
- };
- n.X = (int32_t)v.x;
- n.Y = (int32_t)v.y;
- n.Z = (int32_t)v.z;
- out = t;
-}
-
- // UNREAL vertex decompression
-inline void DecompressVertex(aiVector3D& v, int32_t in)
-{
- union {
- Vertex n;
- int32_t i;
- };
- i = in;
-
- v.x = (float)n.X;
- v.y = (float)n.Y;
- v.z = (float)n.Z;
-}
-
-} // end namespace Unreal
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load UNREAL files (*.3d)
-*/
-class UnrealImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- UnrealImporter();
-
- /** Destructor, private as well */
- ~UnrealImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** @brief Returns whether we can handle the format of the given file
- *
- * See BaseImporter::CanRead() for details.
- **/
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** @brief Called by Importer::GetExtensionList()
- *
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
-
- // -------------------------------------------------------------------
- /** @brief Setup properties for the importer
- *
- * See BaseImporter::SetupProperties() for details
- */
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Imports the given file into the given scene structure.
- *
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- //! frame to be loaded
- uint32_t configFrameID;
-
- //! process surface flags
- bool configHandleFlags;
-
-}; // !class UnrealImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/ValidateDataStructure.cpp b/3rdparty/assimp/code/ValidateDataStructure.cpp
deleted file mode 100644
index 9fc5f420..00000000
--- a/3rdparty/assimp/code/ValidateDataStructure.cpp
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file ValidateDataStructure.cpp
- * @brief Implementation of the post processing step to validate
- * the data structure returned by Assimp.
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "ValidateDataStructure.h"
-#include "BaseImporter.h"
-#include "fast_atof.h"
-#include "ProcessHelper.h"
-
-// CRT headers
-#include <stdarg.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ValidateDSProcess::ValidateDSProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ValidateDSProcess::~ValidateDSProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ValidateDSProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_ValidateDataStructure) != 0;
-}
-// ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
-{
- ai_assert(NULL != 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);
-#ifdef _DEBUG
- aiAssert( szBuffer,__LINE__,__FILE__ );
-#endif
- throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
-}
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::ReportWarning(const char* msg,...)
-{
- ai_assert(NULL != 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);
- DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
-}
-
-// ------------------------------------------------------------------------------------------------
-inline int HasNameMatch(const aiString& in, aiNode* node)
-{
- int result = (node->mName == in ? 1 : 0 );
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- result += HasNameMatch(in,node->mChildren[i]);
- }
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
- // validate all entries
- if (size)
- {
- if (!parray)
- {
- ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
- firstName, secondName, size);
- }
- for (unsigned int i = 0; i < size;++i)
- {
- if (!parray[i])
- {
- ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
- firstName,i,secondName,size);
- }
- Validate(parray[i]);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
- // validate all entries
- if (size)
- {
- if (!parray) {
- ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
- firstName, secondName, size);
- }
- for (unsigned int i = 0; i < size;++i)
- {
- if (!parray[i])
- {
- ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
- firstName,i,secondName,size);
- }
- Validate(parray[i]);
-
- // check whether there are duplicate names
- for (unsigned int a = i+1; a < size;++a)
- {
- if (parray[i]->mName == parray[a]->mName)
- {
- this->ReportError("aiScene::%s[%i] has the same name as "
- "aiScene::%s[%i]",firstName, i,secondName, a);
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidationWithNameCheck(T** array,
- unsigned int size, const char* firstName,
- const char* secondName)
-{
- // validate all entries
- DoValidationEx(array,size,firstName,secondName);
-
- for (unsigned int i = 0; i < size;++i)
- {
- int res = HasNameMatch(array[i]->mName,mScene->mRootNode);
- if (!res) {
- ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)",
- firstName,i,array[i]->mName.data);
- }
- else if (1 != res) {
- ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name",
- firstName,i,array[i]->mName.data);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void ValidateDSProcess::Execute( aiScene* pScene)
-{
- this->mScene = pScene;
- DefaultLogger::get()->debug("ValidateDataStructureProcess begin");
-
- // validate the node graph of the scene
- Validate(pScene->mRootNode);
-
- // validate all meshes
- if (pScene->mNumMeshes) {
- DoValidation(pScene->mMeshes,pScene->mNumMeshes,"mMeshes","mNumMeshes");
- }
- else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
- ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
- }
- else if (pScene->mMeshes) {
- ReportError("aiScene::mMeshes is non-null although there are no meshes");
- }
-
- // validate all animations
- if (pScene->mNumAnimations) {
- DoValidation(pScene->mAnimations,pScene->mNumAnimations,
- "mAnimations","mNumAnimations");
- }
- else if (pScene->mAnimations) {
- ReportError("aiScene::mAnimations is non-null although there are no animations");
- }
-
- // validate all cameras
- if (pScene->mNumCameras) {
- DoValidationWithNameCheck(pScene->mCameras,pScene->mNumCameras,
- "mCameras","mNumCameras");
- }
- else if (pScene->mCameras) {
- ReportError("aiScene::mCameras is non-null although there are no cameras");
- }
-
- // validate all lights
- if (pScene->mNumLights) {
- DoValidationWithNameCheck(pScene->mLights,pScene->mNumLights,
- "mLights","mNumLights");
- }
- else if (pScene->mLights) {
- ReportError("aiScene::mLights is non-null although there are no lights");
- }
-
- // validate all textures
- if (pScene->mNumTextures) {
- DoValidation(pScene->mTextures,pScene->mNumTextures,
- "mTextures","mNumTextures");
- }
- else if (pScene->mTextures) {
- ReportError("aiScene::mTextures is non-null although there are no textures");
- }
-
- // validate all materials
- if (pScene->mNumMaterials) {
- DoValidation(pScene->mMaterials,pScene->mNumMaterials,"mMaterials","mNumMaterials");
- }
-#if 0
- // NOTE: ScenePreprocessor generates a default material if none is there
- else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
- ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
- }
-#endif
- else if (pScene->mMaterials) {
- ReportError("aiScene::mMaterials is non-null although there are no materials");
- }
-
-// if (!has)ReportError("The aiScene data structure is empty");
- DefaultLogger::get()->debug("ValidateDataStructureProcess end");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiLight* pLight)
-{
- if (pLight->mType == aiLightSource_UNDEFINED)
- ReportWarning("aiLight::mType is aiLightSource_UNDEFINED");
-
- if (!pLight->mAttenuationConstant &&
- !pLight->mAttenuationLinear &&
- !pLight->mAttenuationQuadratic) {
- ReportWarning("aiLight::mAttenuationXXX - all are zero");
- }
-
- if (pLight->mAngleInnerCone > pLight->mAngleOuterCone)
- ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone");
-
- if (pLight->mColorDiffuse.IsBlack() && pLight->mColorAmbient.IsBlack()
- && pLight->mColorSpecular.IsBlack())
- {
- ReportWarning("aiLight::mColorXXX - all are black and won't have any influence");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiCamera* pCamera)
-{
- if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
- ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
-
- // FIX: there are many 3ds files with invalid FOVs. No reason to
- // reject them at all ... a warning is appropriate.
- if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
- ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh)
-{
- // validate the material index of the mesh
- if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials)
- {
- ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
- pMesh->mMaterialIndex,mScene->mNumMaterials-1);
- }
-
- Validate(&pMesh->mName);
-
- for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
- {
- aiFace& face = pMesh->mFaces[i];
-
- if (pMesh->mPrimitiveTypes)
- {
- switch (face.mNumIndices)
- {
- case 0:
- ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
- case 1:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
- {
- ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimtiveTypes "
- "does not report the POINT flag",i);
- }
- break;
- case 2:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
- {
- ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimtiveTypes "
- "does not report the LINE flag",i);
- }
- break;
- case 3:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
- {
- ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimtiveTypes "
- "does not report the TRIANGLE flag",i);
- }
- break;
- default:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
- {
- this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimtiveTypes "
- "does not report the POLYGON flag",i);
- }
- break;
- };
- }
-
- if (!face.mIndices)
- ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
- }
-
- // positions must always be there ...
- if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
- ReportError("The mesh contains no vertices");
- }
-
- if (pMesh->mNumVertices > AI_MAX_VERTICES) {
- ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
- }
- if (pMesh->mNumFaces > AI_MAX_FACES) {
- ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
- }
-
- // if tangents are there there must also be bitangent vectors ...
- if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) {
- ReportError("If there are tangents, bitangent vectors must be present as well");
- }
-
- // faces, too
- if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
- ReportError("Mesh contains no faces");
- }
-
- // now check whether the face indexing layout is correct:
- // unique vertices, pseudo-indexed.
- std::vector<bool> abRefList;
- abRefList.resize(pMesh->mNumVertices,false);
- for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
- {
- aiFace& face = pMesh->mFaces[i];
- if (face.mNumIndices > AI_MAX_FACE_INDICES) {
- ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
- }
-
- for (unsigned int a = 0; a < face.mNumIndices;++a)
- {
- if (face.mIndices[a] >= pMesh->mNumVertices) {
- ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
- }
- // the MSB flag is temporarily used by the extra verbose
- // mode to tell us that the JoinVerticesProcess might have
- // been executed already.
- if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && abRefList[face.mIndices[a]])
- {
- ReportError("aiMesh::mVertices[%i] is referenced twice - second "
- "time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
- }
- abRefList[face.mIndices[a]] = true;
- }
- }
-
- // check whether there are vertices that aren't referenced by a face
- bool b = false;
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- if (!abRefList[i])b = true;
- }
- abRefList.clear();
- if (b)ReportWarning("There are unreferenced vertices");
-
- // texture channel 2 may not be set if channel 1 is zero ...
- {
- unsigned int i = 0;
- for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- if (!pMesh->HasTextureCoords(i))break;
- }
- for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- if (pMesh->HasTextureCoords(i))
- {
- ReportError("Texture coordinate channel %i exists "
- "although the previous channel was NULL.",i);
- }
- }
- // the same for the vertex colors
- {
- unsigned int i = 0;
- for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- {
- if (!pMesh->HasVertexColors(i))break;
- }
- for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- if (pMesh->HasVertexColors(i))
- {
- ReportError("Vertex color channel %i is exists "
- "although the previous channel was NULL.",i);
- }
- }
-
-
- // now validate all bones
- if (pMesh->mNumBones)
- {
- if (!pMesh->mBones)
- {
- ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
- pMesh->mNumBones);
- }
- boost::scoped_array<float> afSum(NULL);
- if (pMesh->mNumVertices)
- {
- afSum.reset(new float[pMesh->mNumVertices]);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
- afSum[i] = 0.0f;
- }
-
- // check whether there are duplicate bone names
- for (unsigned int i = 0; i < pMesh->mNumBones;++i)
- {
- const aiBone* bone = pMesh->mBones[i];
- if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
- ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
- }
-
- if (!pMesh->mBones[i])
- {
- ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
- i,pMesh->mNumBones);
- }
- Validate(pMesh,pMesh->mBones[i],afSum.get());
-
- for (unsigned int a = i+1; a < pMesh->mNumBones;++a)
- {
- if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName)
- {
- ReportError("aiMesh::mBones[%i] has the same name as "
- "aiMesh::mBones[%i]",i,a);
- }
- }
- }
- // check whether all bone weights for a vertex sum to 1.0 ...
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
- {
- if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) {
- ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
- }
- }
- }
- else if (pMesh->mBones)
- {
- ReportError("aiMesh::mBones is non-null although there are no bones");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh,
- const aiBone* pBone,float* afSum)
-{
- this->Validate(&pBone->mName);
-
- if (!pBone->mNumWeights) {
- ReportError("aiBone::mNumWeights is zero");
- }
-
- // check whether all vertices affected by this bone are valid
- for (unsigned int i = 0; i < pBone->mNumWeights;++i)
- {
- if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices) {
- ReportError("aiBone::mWeights[%i].mVertexId is out of range",i);
- }
- else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f) {
- ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i);
- }
- afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
-{
- Validate(&pAnimation->mName);
-
- // validate all materials
- if (pAnimation->mNumChannels)
- {
- if (!pAnimation->mChannels) {
- ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
- pAnimation->mNumChannels);
- }
- for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
- {
- if (!pAnimation->mChannels[i])
- {
- ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)",
- i, pAnimation->mNumChannels);
- }
- Validate(pAnimation, pAnimation->mChannels[i]);
- }
- }
- else ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
-
- // Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
- // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
- aiTextureType type)
-{
- const char* szType = TextureTypeToString(type);
-
- // ****************************************************************************
- // Search all keys of the material ...
- // textures must be specified with ascending indices
- // (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
- // ****************************************************************************
-
- int iNumIndices = 0;
- int iIndex = -1;
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type) {
- iIndex = std::max(iIndex, (int) prop->mIndex);
- ++iNumIndices;
-
- if (aiPTI_String != prop->mType)
- ReportError("Material property %s is expected to be a string",prop->mKey.data);
- }
- }
- if (iIndex +1 != iNumIndices) {
- ReportError("%s #%i is set, but there are only %i %s textures",
- szType,iIndex,iNumIndices,szType);
- }
- if (!iNumIndices)return;
- std::vector<aiTextureMapping> mappings(iNumIndices);
-
- // Now check whether all UV indices are valid ...
- bool bNoSpecified = true;
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (prop->mSemantic != type)continue;
-
- if ((int)prop->mIndex >= iNumIndices)
- {
- ReportError("Found texture property with index %i, although there "
- "are only %i textures of type %s",
- prop->mIndex, iNumIndices, szType);
- }
-
- if (!::strcmp(prop->mKey.data,"$tex.mapping")) {
- if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping))
- {
- ReportError("Material property %s%i is expected to be an integer (size is %i)",
- prop->mKey.data,prop->mIndex,prop->mDataLength);
- }
- mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
- }
- else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo")) {
- if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform))
- {
- ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
- prop->mKey.data,prop->mIndex, prop->mDataLength);
- }
- mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
- }
- else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc")) {
- if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength)
- {
- ReportError("Material property %s%i is expected to be an integer (size is %i)",
- prop->mKey.data,prop->mIndex,prop->mDataLength);
- }
- bNoSpecified = false;
-
- // Ignore UV indices for texture channels that are not there ...
-
- // Get the value
- iIndex = *((unsigned int*)prop->mData);
-
- // Check whether there is a mesh using this material
- // which has not enough UV channels ...
- for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
- {
- aiMesh* mesh = this->mScene->mMeshes[a];
- if (mesh->mMaterialIndex == (unsigned int)i)
- {
- int iChannels = 0;
- while (mesh->HasTextureCoords(iChannels))++iChannels;
- if (iIndex >= iChannels)
- {
- ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
- iIndex,prop->mKey.data,a,iChannels);
- }
- }
- }
- }
- }
- if (bNoSpecified)
- {
- // Assume that all textures are using the first UV channel
- for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
- {
- aiMesh* mesh = mScene->mMeshes[a];
- if (mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV)
- {
- if (!mesh->mTextureCoords[0])
- {
- // This is a special case ... it could be that the
- // original mesh format intended the use of a special
- // mapping here.
- ReportWarning("UV-mapped texture, but there are no UV coords");
- }
- }
- }
- }
-}
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
-{
- // check whether there are material keys that are obviously not legal
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- const aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (!prop) {
- ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
- i,pMaterial->mNumProperties);
- }
- if (!prop->mDataLength || !prop->mData) {
- ReportError("aiMaterial::mProperties[%i].mDataLength or "
- "aiMaterial::mProperties[%i].mData is 0",i,i);
- }
- // check all predefined types
- if (aiPTI_String == prop->mType) {
- // FIX: strings are now stored in a less expensive way, but we can't use the
- // validation routine for 'normal' aiStrings
- uint32_t len;
- if (prop->mDataLength < 5 || prop->mDataLength < 4 + (len=*reinterpret_cast<uint32_t*>(prop->mData)) + 1) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain a string (%i, needed: %i)",
- i,prop->mDataLength,sizeof(aiString));
- }
- if (prop->mData[prop->mDataLength-1]) {
- ReportError("Missing null-terminator in string material property");
- }
- // Validate((const aiString*)prop->mData);
- }
- else if (aiPTI_Float == prop->mType) {
- if (prop->mDataLength < sizeof(float)) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain a float (%i, needed: %i)",
- i,prop->mDataLength,sizeof(float));
- }
- }
- else if (aiPTI_Integer == prop->mType) {
- if (prop->mDataLength < sizeof(int)) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain an integer (%i, needed: %i)",
- i,prop->mDataLength,sizeof(int));
- }
- }
- // TODO: check whether there is a key with an unknown name ...
- }
-
- // make some more specific tests
- float fTemp;
- int iShading;
- if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading)) {
- switch ((aiShadingMode)iShading)
- {
- case aiShadingMode_Blinn:
- case aiShadingMode_CookTorrance:
- case aiShadingMode_Phong:
-
- if (AI_SUCCESS != aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS,&fTemp)) {
- ReportWarning("A specular shading model is specified but there is no "
- "AI_MATKEY_SHININESS key");
- }
- if (AI_SUCCESS == aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS_STRENGTH,&fTemp) && !fTemp) {
- ReportWarning("A specular shading model is specified but the value of the "
- "AI_MATKEY_SHININESS_STRENGTH key is 0.0");
- }
- break;
- default: ;
- };
- }
-
- if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01f)) {
- ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
- }
-
- // Check whether there are invalid texture keys
- // TODO: that's a relict of the past, where texture type and index were baked
- // into the material string ... we could do that in one single pass.
- SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE);
- SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR);
- SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT);
- SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE);
- SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY);
- SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS);
- SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT);
- SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS);
- SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT);
- SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP);
- SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiTexture* pTexture)
-{
- // the data section may NEVER be NULL
- if (!pTexture->pcData) {
- ReportError("aiTexture::pcData is NULL");
- }
- if (pTexture->mHeight)
- {
- if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero "
- "(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight);
- }
- else
- {
- if (!pTexture->mWidth) {
- ReportError("aiTexture::mWidth is zero (compressed texture)");
- }
- if ('\0' != pTexture->achFormatHint[3]) {
- ReportWarning("aiTexture::achFormatHint must be zero-terminated");
- }
- else if ('.' == pTexture->achFormatHint[0]) {
- ReportWarning("aiTexture::achFormatHint should contain a file extension "
- "without a leading dot (format hint: %s).",pTexture->achFormatHint);
- }
- }
-
- const char* sz = pTexture->achFormatHint;
- if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
- (sz[1] >= 'A' && sz[1] <= 'Z') ||
- (sz[2] >= 'A' && sz[2] <= 'Z') ||
- (sz[3] >= 'A' && sz[3] <= 'Z')) {
- ReportError("aiTexture::achFormatHint contains non-lowercase letters");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
- const aiNodeAnim* pNodeAnim)
-{
- Validate(&pNodeAnim->mNodeName);
-
- if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys)
- ReportError("Empty node animation channel");
-
- // otherwise check whether one of the keys exceeds the total duration of the animation
- if (pNodeAnim->mNumPositionKeys)
- {
- if (!pNodeAnim->mPositionKeys)
- {
- this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
- pNodeAnim->mNumPositionKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumPositionKeys;++i)
- {
- // ScenePreprocessor will compute the duration if still the default value
- // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
- // seems to be due the compilers register usage/width.
- if (pAnimation->mDuration > 0. && pNodeAnim->mPositionKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mPositionKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mPositionKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mPositionKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mPositionKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mPositionKeys[i].mTime;
- }
- }
- // rotation keys
- if (pNodeAnim->mNumRotationKeys)
- {
- if (!pNodeAnim->mRotationKeys)
- {
- this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
- pNodeAnim->mNumRotationKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumRotationKeys;++i)
- {
- if (pAnimation->mDuration > 0. && pNodeAnim->mRotationKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mRotationKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mRotationKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mRotationKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mRotationKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mRotationKeys[i].mTime;
- }
- }
- // scaling keys
- if (pNodeAnim->mNumScalingKeys)
- {
- if (!pNodeAnim->mScalingKeys) {
- ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)",
- pNodeAnim->mNumScalingKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumScalingKeys;++i)
- {
- if (pAnimation->mDuration > 0. && pNodeAnim->mScalingKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mScalingKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mScalingKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mScalingKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mScalingKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mScalingKeys[i].mTime;
- }
- }
-
- if (!pNodeAnim->mNumScalingKeys && !pNodeAnim->mNumRotationKeys &&
- !pNodeAnim->mNumPositionKeys)
- {
- ReportError("A node animation channel must have at least one subtrack");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiNode* pNode)
-{
- if (!pNode)ReportError("A node of the scenegraph is NULL");
- if (pNode != mScene->mRootNode && !pNode->mParent)
- this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
-
- this->Validate(&pNode->mName);
-
- // validate all meshes
- if (pNode->mNumMeshes)
- {
- if (!pNode->mMeshes)
- {
- ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
- pNode->mNumMeshes);
- }
- std::vector<bool> abHadMesh;
- abHadMesh.resize(mScene->mNumMeshes,false);
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
- {
- if (pNode->mMeshes[i] >= mScene->mNumMeshes)
- {
- ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
- pNode->mMeshes[i],mScene->mNumMeshes-1);
- }
- if (abHadMesh[pNode->mMeshes[i]])
- {
- ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
- i,pNode->mMeshes[i]);
- }
- abHadMesh[pNode->mMeshes[i]] = true;
- }
- }
- if (pNode->mNumChildren)
- {
- if (!pNode->mChildren) {
- ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)",
- pNode->mNumChildren);
- }
- for (unsigned int i = 0; i < pNode->mNumChildren;++i) {
- Validate(pNode->mChildren[i]);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiString* pString)
-{
- if (pString->length > MAXLEN)
- {
- this->ReportError("aiString::length is too large (%i, maximum is %i)",
- pString->length,MAXLEN);
- }
- const char* sz = pString->data;
- while (true)
- {
- if ('\0' == *sz)
- {
- if (pString->length != (unsigned int)(sz-pString->data))
- ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
- break;
- }
- else if (sz >= &pString->data[MAXLEN])
- ReportError("aiString::data is invalid. There is no terminal character");
- ++sz;
- }
-}
diff --git a/3rdparty/assimp/code/ValidateDataStructure.h b/3rdparty/assimp/code/ValidateDataStructure.h
deleted file mode 100644
index 48d12b8f..00000000
--- a/3rdparty/assimp/code/ValidateDataStructure.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a (dummy) post processing step to validate the loader's
- * output data structure (for debugging)
- */
-#ifndef AI_VALIDATEPROCESS_H_INC
-#define AI_VALIDATEPROCESS_H_INC
-
-#include "../include/aiTypes.h"
-#include "BaseProcess.h"
-
-struct aiBone;
-struct aiMesh;
-struct aiAnimation;
-struct aiNodeAnim;
-struct aiTexture;
-struct aiMaterial;
-struct aiNode;
-struct aiString;
-
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------
-/** Validates the whole ASSIMP scene data structure for correctness.
- * ImportErrorException is thrown of the scene is corrupt.*/
-// --------------------------------------------------------------------------------------
-class ASSIMP_API ValidateDSProcess : public BaseProcess
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- ValidateDSProcess();
-
- /** Destructor, private as well */
- ~ValidateDSProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Report a validation error. This will throw an exception,
- * control won't return.
- * @param msg Format string for sprintf().*/
- AI_WONT_RETURN void ReportError(const char* msg,...);
-
-
- // -------------------------------------------------------------------
- /** Report a validation warning. This won't throw an exception,
- * control will return to the callera.
- * @param msg Format string for sprintf().*/
- void ReportWarning(const char* msg,...);
-
-
- // -------------------------------------------------------------------
- /** Validates a mesh
- * @param pMesh Input mesh*/
- void Validate( const aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Validates a bone
- * @param pMesh Input mesh
- * @param pBone Input bone*/
- void Validate( const aiMesh* pMesh,const aiBone* pBone,float* afSum);
-
- // -------------------------------------------------------------------
- /** Validates an animation
- * @param pAnimation Input animation*/
- void Validate( const aiAnimation* pAnimation);
-
- // -------------------------------------------------------------------
- /** Validates a material
- * @param pMaterial Input material*/
- void Validate( const aiMaterial* pMaterial);
-
- // -------------------------------------------------------------------
- /** Search the material data structure for invalid or corrupt
- * texture keys.
- * @param pMaterial Input material
- * @param type Type of the texture*/
- void SearchForInvalidTextures(const aiMaterial* pMaterial,
- aiTextureType type);
-
- // -------------------------------------------------------------------
- /** Validates a texture
- * @param pTexture Input texture*/
- void Validate( const aiTexture* pTexture);
-
- // -------------------------------------------------------------------
- /** Validates a light source
- * @param pLight Input light
- */
- void Validate( const aiLight* pLight);
-
- // -------------------------------------------------------------------
- /** Validates a camera
- * @param pCamera Input camera*/
- void Validate( const aiCamera* pCamera);
-
- // -------------------------------------------------------------------
- /** Validates a bone animation channel
- * @param pAnimation Animation channel.
- * @param pBoneAnim Input bone animation */
- void Validate( const aiAnimation* pAnimation,
- const aiNodeAnim* pBoneAnim);
-
- // -------------------------------------------------------------------
- /** Validates a node and all of its subnodes
- * @param Node Input node*/
- void Validate( const aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** Validates a string
- * @param pString Input string*/
- void Validate( const aiString* pString);
-
-private:
-
- // template to validate one of the aiScene::mXXX arrays
- template <typename T>
- inline void DoValidation(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- // extended version: checks whethr T::mName occurs twice
- template <typename T>
- inline void DoValidationEx(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- // extension to the first template which does also search
- // the nodegraph for an item with the same name
- template <typename T>
- inline void DoValidationWithNameCheck(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- aiScene* mScene;
-};
-
-
-
-
-} // end of namespace Assimp
-
-#endif // AI_VALIDATEPROCESS_H_INC
diff --git a/3rdparty/assimp/code/Vertex.h b/3rdparty/assimp/code/Vertex.h
deleted file mode 100644
index 6fa33dc7..00000000
--- a/3rdparty/assimp/code/Vertex.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-/** @file Defines a helper class to represent an interleaved vertex */
-#ifndef AI_VERTEX_H_INC
-#define AI_VERTEX_H_INC
-namespace Assimp {
-
- ///////////////////////////////////////////////////////////////////////////
- // std::plus-family operates on operands with identical types - we need to
- // support all the (vectype op float) combinations in vector maths.
- // Providing T(float) would open the way to endless implicit conversions.
- ///////////////////////////////////////////////////////////////////////////
- namespace Intern {
- template <typename T0, typename T1, typename TRES = T0> struct plus {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0+t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct minus {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0-t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct multiplies {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0*t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct divides {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0/t1;
- }
- };
- }
-
-// ------------------------------------------------------------------------------------------------
-/** Intermediate description a vertex with all possible components. Defines a full set of
- * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied
- * to *all* vertex components equally. This is useful for stuff like interpolation
- * or subdivision, but won't work if special handling is required for some vertex components. */
-// ------------------------------------------------------------------------------------------------
-class Vertex
-{
- friend Vertex operator + (const Vertex&,const Vertex&);
- friend Vertex operator - (const Vertex&,const Vertex&);
-
- friend Vertex operator + (const Vertex&,float);
- friend Vertex operator - (const Vertex&,float);
- friend Vertex operator * (const Vertex&,float);
- friend Vertex operator / (const Vertex&,float);
-
- friend Vertex operator + (float, const Vertex&);
- friend Vertex operator - (float, const Vertex&);
- friend Vertex operator * (float, const Vertex&);
- friend Vertex operator / (float, const Vertex&);
-
-public:
-
- Vertex() {}
-
- // ----------------------------------------------------------------------------
- /** Extract a particular vertex from a mesh and interleave all components */
- explicit Vertex(const aiMesh* msh, unsigned int idx) {
- ai_assert(idx < msh->mNumVertices);
- position = msh->mVertices[idx];
-
- if (msh->HasNormals()) {
- normal = msh->mNormals[idx];
- }
-
- if (msh->HasTangentsAndBitangents()) {
- tangent = msh->mTangents[idx];
- bitangent = msh->mBitangents[idx];
- }
-
- for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
- texcoords[i] = msh->mTextureCoords[i][idx];
- }
-
- for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
- colors[i] = msh->mColors[i][idx];
- }
- }
-
-public:
-
- Vertex& operator += (const Vertex& v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (const Vertex& v) {
- *this = *this-v;
- return *this;
- }
-
-
-
- Vertex& operator += (float v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (float v) {
- *this = *this-v;
- return *this;
- }
-
- Vertex& operator *= (float v) {
- *this = *this*v;
- return *this;
- }
-
- Vertex& operator /= (float v) {
- *this = *this/v;
- return *this;
- }
-
-public:
-
- // ----------------------------------------------------------------------------
- /** Convert back to non-interleaved storage */
- void SortBack(aiMesh* out, unsigned int idx) const {
-
- ai_assert(idx<out->mNumVertices);
- out->mVertices[idx] = position;
-
- if (out->HasNormals()) {
- out->mNormals[idx] = normal;
- }
-
- if (out->HasTangentsAndBitangents()) {
- out->mTangents[idx] = tangent;
- out->mBitangents[idx] = bitangent;
- }
-
- for (unsigned int i = 0; out->HasTextureCoords(i); ++i) {
- out->mTextureCoords[i][idx] = texcoords[i];
- }
-
- for (unsigned int i = 0; out->HasVertexColors(i); ++i) {
- out->mColors[i][idx] = colors[i];
- }
- }
-
-private:
-
- // ----------------------------------------------------------------------------
- /** Construct from two operands and a binary operation to combine them */
- template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<aiVector3D>()(v0.position,v1.position);
- res.normal = op<aiVector3D>()(v0.normal,v1.normal);
- res.tangent = op<aiVector3D>()(v0.tangent,v1.tangent);
- res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]);
- }
- return res;
- }
-
- // ----------------------------------------------------------------------------
- /** This time binary arithmetics of v0 with a floating-point number */
- template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, float f) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<aiVector3D,float,aiVector3D>()(v0.position,f);
- res.normal = op<aiVector3D,float,aiVector3D>()(v0.normal,f);
- res.tangent = op<aiVector3D,float,aiVector3D>()(v0.tangent,f);
- res.bitangent = op<aiVector3D,float,aiVector3D>()(v0.bitangent,f);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<aiVector3D,float,aiVector3D>()(v0.texcoords[i],f);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<aiColor4D,float,aiColor4D>()(v0.colors[i],f);
- }
- return res;
- }
-
- // ----------------------------------------------------------------------------
- /** This time binary arithmetics of v0 with a floating-point number */
- template <template <typename, typename, typename> class op> static Vertex BinaryOp(float f, const Vertex& v0) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<float,aiVector3D,aiVector3D>()(f,v0.position);
- res.normal = op<float,aiVector3D,aiVector3D>()(f,v0.normal);
- res.tangent = op<float,aiVector3D,aiVector3D>()(f,v0.tangent);
- res.bitangent = op<float,aiVector3D,aiVector3D>()(f,v0.bitangent);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<float,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<float,aiColor4D,aiColor4D>()(f,v0.colors[i]);
- }
- return res;
- }
-
-public:
-
- aiVector3D position;
- aiVector3D normal;
- aiVector3D tangent, bitangent;
-
- aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
-};
-
-
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
- return Vertex::BinaryOp<std::plus>(v0,v1);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
- return Vertex::BinaryOp<std::minus>(v0,v1);
-}
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,float f) {
- return Vertex::BinaryOp<Intern::plus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,float f) {
- return Vertex::BinaryOp<Intern::minus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator * (const Vertex& v0,float f) {
- return Vertex::BinaryOp<Intern::multiplies>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator / (const Vertex& v0,float f) {
- return Vertex::BinaryOp<Intern::divides>(v0,f);
-}
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE Vertex operator + (float f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::plus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator - (float f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::minus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator * (float f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::multiplies>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator / (float f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::divides>(f,v0);
-}
-
-}
-#endif
diff --git a/3rdparty/assimp/code/VertexTriangleAdjacency.cpp b/3rdparty/assimp/code/VertexTriangleAdjacency.cpp
deleted file mode 100644
index 3db25461..00000000
--- a/3rdparty/assimp/code/VertexTriangleAdjacency.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the VertexTriangleAdjacency helper class
- */
-
-#include "AssimpPCH.h"
-
-// internal headers
-#include "VertexTriangleAdjacency.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
- unsigned int iNumFaces,
- unsigned int iNumVertices /*= 0*/,
- bool bComputeNumTriangles /*= false*/)
-{
- // compute the number of referenced vertices if it wasn't specified by the caller
- const aiFace* const pcFaceEnd = pcFaces + iNumFaces;
- if (!iNumVertices) {
-
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
- ai_assert(3 == pcFace->mNumIndices);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[2]);
- }
- }
- unsigned int* pi;
-
- // allocate storage
- if (bComputeNumTriangles) {
- pi = mLiveTriangles = new unsigned int[iNumVertices+1];
- memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1));
- mOffsetTable = new unsigned int[iNumVertices+2]+1;
- }
- else {
- pi = mOffsetTable = new unsigned int[iNumVertices+2]+1;
- memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1));
- mLiveTriangles = NULL; // important, otherwise the d'tor would crash
- }
-
- // get a pointer to the end of the buffer
- unsigned int* piEnd = pi+iNumVertices;
- *piEnd++ = 0u;
-
- // first pass: compute the number of faces referencing each vertex
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace)
- {
- pi[pcFace->mIndices[0]]++;
- pi[pcFace->mIndices[1]]++;
- pi[pcFace->mIndices[2]]++;
- }
-
- // second pass: compute the final offset table
- unsigned int iSum = 0;
- unsigned int* piCurOut = this->mOffsetTable;
- for (unsigned int* piCur = pi; piCur != piEnd;++piCur,++piCurOut) {
-
- unsigned int iLastSum = iSum;
- iSum += *piCur;
- *piCurOut = iLastSum;
- }
- pi = this->mOffsetTable;
-
- // third pass: compute the final table
- this->mAdjacencyTable = new unsigned int[iSum];
- iSum = 0;
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace,++iSum) {
-
- unsigned int idx = pcFace->mIndices[0];
- mAdjacencyTable[pi[idx]++] = iSum;
-
- idx = pcFace->mIndices[1];
- mAdjacencyTable[pi[idx]++] = iSum;
-
- idx = pcFace->mIndices[2];
- mAdjacencyTable[pi[idx]++] = iSum;
- }
- // fourth pass: undo the offset computations made during the third pass
- // We could do this in a separate buffer, but this would be TIMES slower.
- --mOffsetTable;
- *mOffsetTable = 0u;
-}
-// ------------------------------------------------------------------------------------------------
-VertexTriangleAdjacency::~VertexTriangleAdjacency()
-{
- // delete allocated storage
- delete[] mOffsetTable;
- delete[] mAdjacencyTable;
- delete[] mLiveTriangles;
-}
diff --git a/3rdparty/assimp/code/VertexTriangleAdjacency.h b/3rdparty/assimp/code/VertexTriangleAdjacency.h
deleted file mode 100644
index 2929b0c0..00000000
--- a/3rdparty/assimp/code/VertexTriangleAdjacency.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Defines a helper class to compute a vertex-triangle adjacency map */
-#ifndef AI_VTADJACENCY_H_INC
-#define AI_VTADJACENCY_H_INC
-
-#include "BaseProcess.h"
-#include "../include/aiTypes.h"
-#include "../include/aiAssert.h"
-
-struct aiMesh;
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------------
-/** @brief The VertexTriangleAdjacency class computes a vertex-triangle
- * adjacency map from a given index buffer.
- *
- * @note Although it is called #VertexTriangleAdjacency, the current version does also
- * support arbitrary polygons. */
-// --------------------------------------------------------------------------------------------
-class ASSIMP_API VertexTriangleAdjacency
-{
-public:
-
- // ----------------------------------------------------------------------------
- /** @brief Construction from an existing index buffer
- * @param pcFaces Index buffer
- * @param iNumFaces Number of faces in the buffer
- * @param iNumVertices Number of referenced vertices. This value
- * is computed automatically if 0 is specified.
- * @param bComputeNumTriangles If you want the class to compute
- * a list containing the number of referenced triangles per vertex
- * per vertex - pass true. */
- VertexTriangleAdjacency(aiFace* pcFaces,unsigned int iNumFaces,
- unsigned int iNumVertices = 0,
- bool bComputeNumTriangles = true);
-
-
- // ----------------------------------------------------------------------------
- /** @brief Destructor */
- ~VertexTriangleAdjacency();
-
-
-public:
-
- // ----------------------------------------------------------------------------
- /** @brief Get all triangles adjacent to a vertex
- * @param iVertIndex Index of the vertex
- * @return A pointer to the adjacency list. */
- unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
- {
- ai_assert(iVertIndex < iNumVertices);
- return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
- }
-
-
- // ----------------------------------------------------------------------------
- /** @brief Get the number of triangles that are referenced by
- * a vertex. This function returns a reference that can be modified
- * @param iVertIndex Index of the vertex
- * @return Number of referenced triangles */
- unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
- {
- ai_assert(iVertIndex < iNumVertices && NULL != mLiveTriangles);
- return mLiveTriangles[iVertIndex];
- }
-
-
-public:
-
- //! Offset table
- unsigned int* mOffsetTable;
-
- //! Adjacency table
- unsigned int* mAdjacencyTable;
-
- //! Table containing the number of referenced triangles per vertex
- unsigned int* mLiveTriangles;
-
- //! Debug: Number of referenced vertices
- unsigned int iNumVertices;
-
-};
-}
-
-#endif // !! AI_VTADJACENCY_H_INC
diff --git a/3rdparty/assimp/code/Win32DebugLogStream.h b/3rdparty/assimp/code/Win32DebugLogStream.h
deleted file mode 100644
index db19108c..00000000
--- a/3rdparty/assimp/code/Win32DebugLogStream.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef AI_WIN32DEBUGLOGSTREAM_H_INC
-#define AI_WIN32DEBUGLOGSTREAM_H_INC
-
-#ifdef WIN32
-
-#include "../include/LogStream.h"
-#include "Windows.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @class Win32DebugLogStream
- * @brief Logs into the debug stream from win32.
- */
-class Win32DebugLogStream :
- public LogStream
-{
-public:
- /** @brief Default constructor */
- Win32DebugLogStream();
-
- /** @brief Destructor */
- ~Win32DebugLogStream();
-
- /** @brief Writer */
- void write(const char* messgae);
-};
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline Win32DebugLogStream::Win32DebugLogStream()
-{}
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline Win32DebugLogStream::~Win32DebugLogStream()
-{}
-
-// ---------------------------------------------------------------------------
-// Write method
-inline void Win32DebugLogStream::write(const char* message)
-{
- OutputDebugStringA( message);
-}
-
-// ---------------------------------------------------------------------------
-} // Namespace Assimp
-
-#endif // ! WIN32
-#endif // guard
diff --git a/3rdparty/assimp/code/XFileHelper.h b/3rdparty/assimp/code/XFileHelper.h
deleted file mode 100644
index 23b8f77c..00000000
--- a/3rdparty/assimp/code/XFileHelper.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-
-/** @file Defines the helper data structures for importing XFiles */
-#ifndef AI_XFILEHELPER_H_INC
-#define AI_XFILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-
-#include "../include/aiTypes.h"
-#include "../include/aiQuaternion.h"
-#include "../include/aiMesh.h"
-#include "../include/aiAnim.h"
-
-namespace Assimp
-{
-namespace XFile
-{
-
-/** Helper structure representing a XFile mesh face */
-struct Face
-{
- std::vector<unsigned int> mIndices;
-};
-
-/** Helper structure representing a texture filename inside a material and its potential source */
-struct TexEntry
-{
- std::string mName;
- bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
-
- TexEntry() { mIsNormalMap = false; }
- TexEntry( const std::string& pName, bool pIsNormalMap = false)
- : mName( pName), mIsNormalMap( pIsNormalMap)
- { /* done */ }
-};
-
-/** Helper structure representing a XFile material */
-struct Material
-{
- std::string mName;
- bool mIsReference; // if true, mName holds a name by which the actual material can be found in the material list
- aiColor4D mDiffuse;
- float mSpecularExponent;
- aiColor3D mSpecular;
- aiColor3D mEmissive;
- std::vector<TexEntry> mTextures;
-
- Material() { mIsReference = false; }
-};
-
-/** Helper structure to represent a bone weight */
-struct BoneWeight
-{
- unsigned int mVertex;
- float mWeight;
-};
-
-/** Helper structure to represent a bone in a mesh */
-struct Bone
-{
- std::string mName;
- std::vector<BoneWeight> mWeights;
- aiMatrix4x4 mOffsetMatrix;
-};
-
-/** Helper structure to represent an XFile mesh */
-struct Mesh
-{
- std::vector<aiVector3D> mPositions;
- std::vector<Face> mPosFaces;
- std::vector<aiVector3D> mNormals;
- std::vector<Face> mNormFaces;
- unsigned int mNumTextures;
- std::vector<aiVector2D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- unsigned int mNumColorSets;
- std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- std::vector<unsigned int> mFaceMaterials;
- std::vector<Material> mMaterials;
-
- std::vector<Bone> mBones;
-
- Mesh() { mNumTextures = 0; mNumColorSets = 0; }
-};
-
-/** Helper structure to represent a XFile frame */
-struct Node
-{
- std::string mName;
- aiMatrix4x4 mTrafoMatrix;
- Node* mParent;
- std::vector<Node*> mChildren;
- std::vector<Mesh*> mMeshes;
-
- Node() { mParent = NULL; }
- Node( Node* pParent) { mParent = pParent; }
- ~Node()
- {
- for ( unsigned int a = 0; a < mChildren.size(); a++)
- delete mChildren[a];
- for ( unsigned int a = 0; a < mMeshes.size(); a++)
- delete mMeshes[a];
- }
-};
-
-struct MatrixKey
-{
- double mTime;
- aiMatrix4x4 mMatrix;
-};
-
-/** Helper structure representing a single animated bone in a XFile */
-struct AnimBone
-{
- std::string mBoneName;
- std::vector<aiVectorKey> mPosKeys; // either three separate key sequences for position, rotation, scaling
- std::vector<aiQuatKey> mRotKeys;
- std::vector<aiVectorKey> mScaleKeys;
- std::vector<MatrixKey> mTrafoKeys; // or a combined key sequence of transformation matrices.
-};
-
-/** Helper structure to represent an animation set in a XFile */
-struct Animation
-{
- std::string mName;
- std::vector<AnimBone*> mAnims;
-
- ~Animation()
- {
- for ( unsigned int a = 0; a < mAnims.size(); a++)
- delete mAnims[a];
- }
-};
-
-/** Helper structure analogue to aiScene */
-struct Scene
-{
- Node* mRootNode;
-
- std::vector<Mesh*> mGlobalMeshes; // global meshes found outside of any frames
- std::vector<Material> mGlobalMaterials; // global materials found outside of any meshes.
-
- std::vector<Animation*> mAnims;
- unsigned int mAnimTicksPerSecond;
-
- Scene() { mRootNode = NULL; mAnimTicksPerSecond = 0; }
- ~Scene()
- {
- delete mRootNode;
- for ( unsigned int a = 0; a < mGlobalMeshes.size(); a++)
- delete mGlobalMeshes[a];
- for ( unsigned int a = 0; a < mAnims.size(); a++)
- delete mAnims[a];
- }
-};
-
-} // end of namespace XFile
-} // end of namespace Assimp
-
-#endif // AI_XFILEHELPER_H_INC
diff --git a/3rdparty/assimp/code/XFileImporter.cpp b/3rdparty/assimp/code/XFileImporter.cpp
deleted file mode 100644
index 1abfb1f2..00000000
--- a/3rdparty/assimp/code/XFileImporter.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-/** @file XFileImporter.cpp
- * @brief Implementation of the XFile importer class
- */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-
-#include "XFileImporter.h"
-#include "XFileParser.h"
-#include "ConvertToLHProcess.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-XFileImporter::XFileImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-XFileImporter::~XFileImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
- if (extension == "x") {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint32_t token[1];
- token[0] = AI_MAKE_MAGIC("xof ");
- return CheckMagicToken(pIOHandler,pFile,token,1,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- extensions.insert("x");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- // read file into memory
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
- if ( file.get() == NULL)
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- size_t fileSize = file->FileSize();
- if ( fileSize < 16)
- throw DeadlyImportError( "XFile is too small.");
-
- // need to clear members - this method might be called multiple
- // times on a single XFileImporter instance.
- mImportedMats.clear();
-
- // in the hope that binary files will never start with a BOM ...
- mBuffer.resize( fileSize);
- file->Read( &mBuffer.front(), 1, fileSize);
- ConvertToUTF8(mBuffer);
-
- // parse the file into a temporary representation
- XFileParser parser( mBuffer);
-
- // and create the proper return structures out of it
- CreateDataRepresentationFromImport( pScene, parser.GetImportedData());
-
- // if nothing came from it, report it as error
- if ( !pScene->mRootNode)
- throw DeadlyImportError( "XFile is ill-formatted - no content imported.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the return data structure out of the imported data.
-void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, const XFile::Scene* pData)
-{
- // Read the global materials first so that meshes referring to them can find them later
- ConvertMaterials( pScene, pData->mGlobalMaterials);
-
- // copy nodes, extracting meshes and materials on the way
- pScene->mRootNode = CreateNodes( pScene, NULL, pData->mRootNode);
-
- // extract animations
- CreateAnimations( pScene, pData);
-
- // read the global meshes that were stored outside of any node
- if ( pData->mGlobalMeshes.size() > 0)
- {
- // create a root node to hold them if there isn't any, yet
- if ( pScene->mRootNode == NULL)
- {
- pScene->mRootNode = new aiNode;
- pScene->mRootNode->mName.Set( "$dummy_node");
- }
-
- // convert all global meshes and store them in the root node.
- // If there was one before, the global meshes now suddenly have its transformation matrix...
- // Don't know what to do there, I don't want to insert another node under the present root node
- // just to avoid this.
- CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes);
- }
-
- // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
- MakeLeftHandedProcess convertProcess;
- convertProcess.Execute( pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-
- // finally: create a dummy material if not material was imported
- if ( pScene->mNumMaterials == 0)
- {
- pScene->mNumMaterials = 1;
- // create the Material
- Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
- int shadeMode = (int) aiShadingMode_Gouraud;
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- // material colours
- int specExp = 1;
-
- aiColor3D clr = aiColor3D( 0, 0, 0);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_EMISSIVE);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_SPECULAR);
-
- clr = aiColor3D( 0.5f, 0.5f, 0.5f);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
-
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = mat;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively creates scene nodes from the imported hierarchy.
-aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFile::Node* pNode)
-{
- if ( !pNode)
- return NULL;
-
- // create node
- aiNode* node = new aiNode;
- node->mName.length = pNode->mName.length();
- node->mParent = pParent;
- memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
- node->mName.data[node->mName.length] = 0;
- node->mTransformation = pNode->mTrafoMatrix;
-
- // convert meshes from the source node
- CreateMeshes( pScene, node, pNode->mMeshes);
-
- // handle childs
- if ( pNode->mChildren.size() > 0)
- {
- node->mNumChildren = (unsigned int)pNode->mChildren.size();
- node->mChildren = new aiNode* [node->mNumChildren];
-
- for ( unsigned int a = 0; a < pNode->mChildren.size(); a++)
- node->mChildren[a] = CreateNodes( pScene, node, pNode->mChildren[a]);
- }
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the meshes for the given node.
-void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes)
-{
- if ( pMeshes.size() == 0)
- return;
-
- // create a mesh for each mesh-material combination in the source node
- std::vector<aiMesh*> meshes;
- for ( unsigned int a = 0; a < pMeshes.size(); a++)
- {
- const XFile::Mesh* sourceMesh = pMeshes[a];
- // first convert its materials so that we can find them when searching by name afterwards
- ConvertMaterials( pScene, sourceMesh->mMaterials);
-
- unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u);
- for ( unsigned int b = 0; b < numMaterials; b++)
- {
- // collect the faces belonging to this material
- std::vector<unsigned int> faces;
- unsigned int numVertices = 0;
- if ( sourceMesh->mFaceMaterials.size() > 0)
- {
- // if there is a per-face material defined, select the faces with the corresponding material
- for ( unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); c++)
- {
- if ( sourceMesh->mFaceMaterials[c] == b)
- {
- faces.push_back( c);
- numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
- }
- }
- } else
- {
- // if there is no per-face material, place everything into one mesh
- for ( unsigned int c = 0; c < sourceMesh->mPosFaces.size(); c++)
- {
- faces.push_back( c);
- numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
- }
- }
-
- // no faces/vertices using this material? strange...
- if ( numVertices == 0)
- continue;
-
- // create a submesh using this material
- aiMesh* mesh = new aiMesh;
- meshes.push_back( mesh);
-
- // find the material by name in the scene's material list. Either own material
- // or referenced material, it should already be found there
- if ( sourceMesh->mFaceMaterials.size() > 0)
- {
- std::map<std::string, unsigned int>::const_iterator matIt = mImportedMats.find( sourceMesh->mMaterials[b].mName);
- if ( matIt == mImportedMats.end())
- mesh->mMaterialIndex = 0;
- else
- mesh->mMaterialIndex = matIt->second;
- } else
- {
- mesh->mMaterialIndex = 0;
- }
-
- // Create properly sized data arrays in the mesh. We store unique vertices per face,
- // as specified
- mesh->mNumVertices = numVertices;
- mesh->mVertices = new aiVector3D[numVertices];
- mesh->mNumFaces = (unsigned int)faces.size();
- mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- // normals?
- if ( sourceMesh->mNormals.size() > 0)
- mesh->mNormals = new aiVector3D[numVertices];
- // texture coords
- for ( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++)
- {
- if ( sourceMesh->mTexCoords[c].size() > 0)
- mesh->mTextureCoords[c] = new aiVector3D[numVertices];
- }
- // vertex colors
- for ( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++)
- {
- if ( sourceMesh->mColors[c].size() > 0)
- mesh->mColors[c] = new aiColor4D[numVertices];
- }
-
- // now collect the vertex data of all data streams present in the imported mesh
- unsigned int newIndex = 0;
- std::vector<unsigned int> orgPoints; // from which original point each new vertex stems
- orgPoints.resize( numVertices, 0);
-
- for ( unsigned int c = 0; c < faces.size(); c++)
- {
- unsigned int f = faces[c]; // index of the source face
- const XFile::Face& pf = sourceMesh->mPosFaces[f]; // position source face
-
- // create face. either triangle or triangle fan depending on the index count
- aiFace& df = mesh->mFaces[c]; // destination face
- df.mNumIndices = (unsigned int)pf.mIndices.size();
- df.mIndices = new unsigned int[ df.mNumIndices];
-
- // collect vertex data for indices of this face
- for ( unsigned int d = 0; d < df.mNumIndices; d++)
- {
- df.mIndices[d] = newIndex;
- orgPoints[newIndex] = pf.mIndices[d];
-
- // Position
- mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]];
- // Normal, if present
- if ( mesh->HasNormals())
- mesh->mNormals[newIndex] = sourceMesh->mNormals[sourceMesh->mNormFaces[f].mIndices[d]];
-
- // texture coord sets
- for ( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++)
- {
- if ( mesh->HasTextureCoords( e))
- {
- aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]];
- mesh->mTextureCoords[e][newIndex] = aiVector3D( tex.x, 1.0f - tex.y, 0.0f);
- }
- }
- // vertex color sets
- for ( unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; e++)
- if ( mesh->HasVertexColors( e))
- mesh->mColors[e][newIndex] = sourceMesh->mColors[e][pf.mIndices[d]];
-
- newIndex++;
- }
- }
-
- // there should be as much new vertices as we calculated before
- assert( newIndex == numVertices);
-
- // convert all bones of the source mesh which influence vertices in this newly created mesh
- const std::vector<XFile::Bone>& bones = sourceMesh->mBones;
- std::vector<aiBone*> newBones;
- for ( unsigned int c = 0; c < bones.size(); c++)
- {
- const XFile::Bone& obone = bones[c];
- // set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
- std::vector<float> oldWeights( sourceMesh->mPositions.size(), 0.0f);
- for ( unsigned int d = 0; d < obone.mWeights.size(); d++)
- oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
-
- // collect all vertex weights that influence a vertex in the new mesh
- std::vector<aiVertexWeight> newWeights;
- newWeights.reserve( numVertices);
- for ( unsigned int d = 0; d < orgPoints.size(); d++)
- {
- // does the new vertex stem from an old vertex which was influenced by this bone?
- float w = oldWeights[orgPoints[d]];
- if ( w > 0.0f)
- newWeights.push_back( aiVertexWeight( d, w));
- }
-
- // if the bone has no weights in the newly created mesh, ignore it
- if ( newWeights.size() == 0)
- continue;
-
- // create
- aiBone* nbone = new aiBone;
- newBones.push_back( nbone);
- // copy name and matrix
- nbone->mName.Set( obone.mName);
- nbone->mOffsetMatrix = obone.mOffsetMatrix;
- nbone->mNumWeights = (unsigned int)newWeights.size();
- nbone->mWeights = new aiVertexWeight[nbone->mNumWeights];
- for ( unsigned int d = 0; d < newWeights.size(); d++)
- nbone->mWeights[d] = newWeights[d];
- }
-
- // store the bones in the mesh
- mesh->mNumBones = (unsigned int)newBones.size();
- if ( newBones.size() > 0)
- {
- mesh->mBones = new aiBone*[mesh->mNumBones];
- std::copy( newBones.begin(), newBones.end(), mesh->mBones);
- }
- }
- }
-
- // reallocate scene mesh array to be large enough
- aiMesh** prevArray = pScene->mMeshes;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes + meshes.size()];
- if ( prevArray)
- {
- memcpy( pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof( aiMesh*));
- delete [] prevArray;
- }
-
- // allocate mesh index array in the node
- pNode->mNumMeshes = (unsigned int)meshes.size();
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
-
- // store all meshes in the mesh library of the scene and store their indices in the node
- for ( unsigned int a = 0; a < meshes.size(); a++)
- {
- pScene->mMeshes[pScene->mNumMeshes] = meshes[a];
- pNode->mMeshes[a] = pScene->mNumMeshes;
- pScene->mNumMeshes++;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the animations from the given imported data and creates them in the scene.
-void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData)
-{
- std::vector<aiAnimation*> newAnims;
-
- for ( unsigned int a = 0; a < pData->mAnims.size(); a++)
- {
- const XFile::Animation* anim = pData->mAnims[a];
- // some exporters mock me with empty animation tags.
- if ( anim->mAnims.size() == 0)
- continue;
-
- // create a new animation to hold the data
- aiAnimation* nanim = new aiAnimation;
- newAnims.push_back( nanim);
- nanim->mName.Set( anim->mName);
- // duration will be determined by the maximum length
- nanim->mDuration = 0;
- nanim->mTicksPerSecond = pData->mAnimTicksPerSecond;
- nanim->mNumChannels = (unsigned int)anim->mAnims.size();
- nanim->mChannels = new aiNodeAnim*[nanim->mNumChannels];
-
- for ( unsigned int b = 0; b < anim->mAnims.size(); b++)
- {
- const XFile::AnimBone* bone = anim->mAnims[b];
- aiNodeAnim* nbone = new aiNodeAnim;
- nbone->mNodeName.Set( bone->mBoneName);
- nanim->mChannels[b] = nbone;
-
- // keyframes are given as combined transformation matrix keys
- if ( bone->mTrafoKeys.size() > 0)
- {
- nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
- nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
- nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
-
- for ( unsigned int c = 0; c < bone->mTrafoKeys.size(); c++)
- {
- // deconstruct each matrix into separate position, rotation and scaling
- double time = bone->mTrafoKeys[c].mTime;
- aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix;
-
- // extract position
- aiVector3D pos( trafo.a4, trafo.b4, trafo.c4);
-
- nbone->mPositionKeys[c].mTime = time;
- nbone->mPositionKeys[c].mValue = pos;
-
- // extract scaling
- aiVector3D scale;
- scale.x = aiVector3D( trafo.a1, trafo.b1, trafo.c1).Length();
- scale.y = aiVector3D( trafo.a2, trafo.b2, trafo.c2).Length();
- scale.z = aiVector3D( trafo.a3, trafo.b3, trafo.c3).Length();
- nbone->mScalingKeys[c].mTime = time;
- nbone->mScalingKeys[c].mValue = scale;
-
- // reconstruct rotation matrix without scaling
- aiMatrix3x3 rotmat(
- trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z,
- trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z,
- trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z);
-
- // and convert it into a quaternion
- nbone->mRotationKeys[c].mTime = time;
- nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
- }
-
- // longest lasting key sequence determines duration
- nanim->mDuration = std::max( nanim->mDuration, bone->mTrafoKeys.back().mTime);
- } else
- {
- // separate key sequences for position, rotation, scaling
- nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size();
- nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
- for ( unsigned int c = 0; c < nbone->mNumPositionKeys; c++)
- {
- aiVector3D pos = bone->mPosKeys[c].mValue;
-
- nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime;
- nbone->mPositionKeys[c].mValue = pos;
- }
-
- // rotation
- nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size();
- nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
- for ( unsigned int c = 0; c < nbone->mNumRotationKeys; c++)
- {
- aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix();
-
- nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime;
- nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
- nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion
- }
-
- // scaling
- nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size();
- nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
- for ( unsigned int c = 0; c < nbone->mNumScalingKeys; c++)
- nbone->mScalingKeys[c] = bone->mScaleKeys[c];
-
- // longest lasting key sequence determines duration
- if ( bone->mPosKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mPosKeys.back().mTime);
- if ( bone->mRotKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mRotKeys.back().mTime);
- if ( bone->mScaleKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mScaleKeys.back().mTime);
- }
- }
- }
-
- // store all converted animations in the scene
- if ( newAnims.size() > 0)
- {
- pScene->mNumAnimations = (unsigned int)newAnims.size();
- pScene->mAnimations = new aiAnimation* [pScene->mNumAnimations];
- for ( unsigned int a = 0; a < newAnims.size(); a++)
- pScene->mAnimations[a] = newAnims[a];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts all materials in the given array and stores them in the scene's material list.
-void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::Material>& pMaterials)
-{
- // count the non-referrer materials in the array
- unsigned int numMaterials = 0;
- for ( unsigned int a = 0; a < pMaterials.size(); a++)
- if ( !pMaterials[a].mIsReference)
- numMaterials++;
-
- if ( numMaterials == 0)
- return;
-
- // resize the scene's material list to offer enough space for the new materials
- aiMaterial** prevMats = pScene->mMaterials;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numMaterials];
- if ( prevMats)
- {
- memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*));
- delete [] prevMats;
- }
-
- // convert all the materials given in the array
- for ( unsigned int a = 0; a < pMaterials.size(); a++)
- {
- const XFile::Material& oldMat = pMaterials[a];
- if ( oldMat.mIsReference)
- continue;
-
- Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
- aiString name;
- name.Set( oldMat.mName);
- mat->AddProperty( &name, AI_MATKEY_NAME);
-
- // Shading model: hardcoded to PHONG, there is no such information in an XFile
- // FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix
- // for some models in the SDK (e.g. good old tiny.x)
- int shadeMode = (int)oldMat.mSpecularExponent == 0.0f
- ? aiShadingMode_Gouraud : aiShadingMode_Phong;
-
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- // material colours
- // FIX: Setup this as ambient not as emissive color
- mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT);
- mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
-
-
- // texture, if there is one
- if (1 == oldMat.mTextures.size())
- {
- const XFile::TexEntry& otex = oldMat.mTextures.back();
- if (otex.mName.length())
- {
- // if there is only one texture assume it contains the diffuse color
- aiString tex( otex.mName);
- if ( otex.mIsNormalMap)
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(0));
- else
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
- else
- {
- // Otherwise ... try to search for typical strings in the
- // texture's file name like 'bump' or 'diffuse'
- unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
- for ( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
- {
- const XFile::TexEntry& otex = oldMat.mTextures[b];
- std::string sz = otex.mName;
- if (!sz.length())continue;
-
-
- // find the file name
- //const size_t iLen = sz.length();
- std::string::size_type s = sz.find_last_of("\\/");
- if (std::string::npos == s)
- s = 0;
-
- // cut off the file extension
- std::string::size_type sExt = sz.find_last_of('.');
- if (std::string::npos != sExt){
- sz[sExt] = '\0';
- }
-
- // convert to lower case for easier comparision
- for ( unsigned int c = 0; c < sz.length(); c++)
- if ( isalpha( sz[c]))
- sz[c] = tolower( sz[c]);
-
-
- // Place texture filename property under the corresponding name
- aiString tex( oldMat.mTextures[b].mName);
-
- // bump map
- if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++));
- } else
- if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++));
- } else
- if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++));
- } else
- if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++));
- } else
- if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++));
- } else
- {
- // Assume it is a diffuse texture
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++));
- }
- }
- }
-
- pScene->mMaterials[pScene->mNumMaterials] = mat;
- mImportedMats[oldMat.mName] = pScene->mNumMaterials;
- pScene->mNumMaterials++;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
-
diff --git a/3rdparty/assimp/code/XFileImporter.h b/3rdparty/assimp/code/XFileImporter.h
deleted file mode 100644
index 8e4b1fbe..00000000
--- a/3rdparty/assimp/code/XFileImporter.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file XFileImporter.h
- * @brief Definition of the XFile importer class.
- */
-#ifndef AI_XFILEIMPORTER_H_INC
-#define AI_XFILEIMPORTER_H_INC
-
-#include <map>
-
-#include "XFileHelper.h"
-#include "BaseImporter.h"
-
-#include "../include/aiTypes.h"
-
-struct aiNode;
-
-namespace Assimp {
-
-namespace XFile {
-struct Scene;
-struct Node;
-}
-
-// ---------------------------------------------------------------------------
-/** The XFileImporter is a worker class capable of importing a scene from a
- * DirectX file .x
- */
-class XFileImporter : public BaseImporter
-{
- friend class Importer;
-
-protected:
- /** Constructor to be privately used by Importer */
- XFileImporter();
-
- /** Destructor, private as well */
- ~XFileImporter();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool CheckSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Called by Importer::GetExtensionList() for each loaded importer.
- * See BaseImporter::GetExtensionList() for details
- */
- void GetExtensionList(std::set<std::string>& extensions);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Constructs the return data structure out of the imported data.
- * @param pScene The scene to construct the return data in.
- * @param pData The imported data in the internal temporary
- * representation.
- */
- void CreateDataRepresentationFromImport( aiScene* pScene,
- const XFile::Scene* pData);
-
- // -------------------------------------------------------------------
- /** Recursively creates scene nodes from the imported hierarchy.
- * The meshes and materials of the nodes will be extracted on the way.
- * @param pScene The scene to construct the return data in.
- * @param pParent The parent node where to create new child nodes
- * @param pNode The temporary node to copy.
- * @return The created node
- */
- aiNode* CreateNodes( aiScene* pScene, aiNode* pParent,
- const XFile::Node* pNode);
-
- // -------------------------------------------------------------------
- /** Converts all meshes in the given mesh array. Each mesh is splitted
- * up per material, the indices of the generated meshes are stored in
- * the node structure.
- * @param pScene The scene to construct the return data in.
- * @param pNode The target node structure that references the
- * constructed meshes.
- * @param pMeshes The array of meshes to convert
- */
- void CreateMeshes( aiScene* pScene, aiNode* pNode,
- const std::vector<XFile::Mesh*>& pMeshes);
-
- // -------------------------------------------------------------------
- /** Converts the animations from the given imported data and creates
- * them in the scene.
- * @param pScene The scene to hold to converted animations
- * @param pData The data to read the animations from
- */
- void CreateAnimations( aiScene* pScene, const XFile::Scene* pData);
-
- // -------------------------------------------------------------------
- /** Converts all materials in the given array and stores them in the
- * scene's material list.
- * @param pScene The scene to hold the converted materials.
- * @param pMaterials The material array to convert.
- */
- void ConvertMaterials( aiScene* pScene,
- const std::vector<XFile::Material>& pMaterials);
-
-protected:
- /** Buffer to hold the loaded file */
- std::vector<char> mBuffer;
-
- /** Imported materials: index in the scene's material list by name */
- std::map<std::string, unsigned int> mImportedMats;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_BASEIMPORTER_H_INC
diff --git a/3rdparty/assimp/code/XFileParser.cpp b/3rdparty/assimp/code/XFileParser.cpp
deleted file mode 100644
index 93ada731..00000000
--- a/3rdparty/assimp/code/XFileParser.cpp
+++ /dev/null
@@ -1,1434 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file Implementation of the XFile parser helper class */
-
-#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-
-#include "XFileParser.h"
-#include "XFileHelper.h"
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace Assimp::XFile;
-
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
-
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include "../contrib/zlib/zlib.h"
-# endif
-
-// Magic identifier for MSZIP compressed data
-#define MSZIP_MAGIC 0x4B43
-#define MSZIP_BLOCK 32786
-
-// ------------------------------------------------------------------------------------------------
-// Dummy memory wrappers for use with zlib
-static void* dummy_alloc (void* /*opaque*/, unsigned int items, unsigned int size) {
- return ::operator new(items*size);
-}
-
-static void dummy_free (void* /*opaque*/, void* address) {
- return ::operator delete(address);
-}
-
-#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
-
-// ------------------------------------------------------------------------------------------------
-// Constructor. Creates a data structure out of the XFile given in the memory block.
-XFileParser::XFileParser( const std::vector<char>& pBuffer)
-{
- mMajorVersion = mMinorVersion = 0;
- mIsBinaryFormat = false;
- mBinaryNumCount = 0;
- P = End = NULL;
- mLineNumber = 0;
- mScene = NULL;
-
- // vector to store uncompressed file for INFLATE'd X files
- std::vector<char> uncompressed;
-
- // set up memory pointers
- P = &pBuffer.front();
- End = P + pBuffer.size();
-
- // check header
- if ( strncmp( P, "xof ", 4) != 0)
- throw DeadlyImportError( "Header mismatch, file is not an XFile.");
-
- // read version. It comes in a four byte format such as "0302"
- mMajorVersion = (unsigned int)(P[4] - 48) * 10 + (unsigned int)(P[5] - 48);
- mMinorVersion = (unsigned int)(P[6] - 48) * 10 + (unsigned int)(P[7] - 48);
-
- bool compressed = false;
-
- // txt - pure ASCII text format
- if ( strncmp( P + 8, "txt ", 4) == 0)
- mIsBinaryFormat = false;
-
- // bin - Binary format
- else if ( strncmp( P + 8, "bin ", 4) == 0)
- mIsBinaryFormat = true;
-
- // tzip - Inflate compressed text format
- else if ( strncmp( P + 8, "tzip", 4) == 0)
- {
- mIsBinaryFormat = false;
- compressed = true;
- }
- // bzip - Inflate compressed binary format
- else if ( strncmp( P + 8, "bzip", 4) == 0)
- {
- mIsBinaryFormat = true;
- compressed = true;
- }
- else ThrowException( boost::str(boost::format("Unsupported xfile format '%c%c%c%c'")
- % P[8] % P[9] % P[10] % P[11]));
-
- // float size
- mBinaryFloatSize = (unsigned int)(P[12] - 48) * 1000
- + (unsigned int)(P[13] - 48) * 100
- + (unsigned int)(P[14] - 48) * 10
- + (unsigned int)(P[15] - 48);
-
- if ( mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
- ThrowException( boost::str( boost::format( "Unknown float size %1% specified in xfile header.")
- % mBinaryFloatSize));
-
- P += 16;
-
- // If this is a compressed X file, apply the inflate algorithm to it
- if (compressed)
- {
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_X
- throw DeadlyImportError("Assimp was built without compressed X support");
-#else
- /* ///////////////////////////////////////////////////////////////////////
- * COMPRESSED X FILE FORMAT
- * ///////////////////////////////////////////////////////////////////////
- * [xhead]
- * 2 major
- * 2 minor
- * 4 type // bzip,tzip
- * [mszip_master_head]
- * 4 unkn // checksum?
- * 2 unkn // flags? (seems to be constant)
- * [mszip_head]
- * 2 ofs // offset to next section
- * 2 magic // 'CK'
- * ... ofs bytes of data
- * ... next mszip_head
- *
- * http://www.kdedevelopers.org/node/3181 has been very helpful.
- * ///////////////////////////////////////////////////////////////////////
- */
-
- // build a zlib stream
- z_stream stream;
- stream.opaque = NULL;
- stream.zalloc = &dummy_alloc;
- stream.zfree = &dummy_free;
- stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
-
- // initialize the inflation algorithm
- ::inflateInit2(&stream, -MAX_WBITS);
-
- // skip unknown data (checksum, flags?)
- P += 6;
-
- // First find out how much storage we'll need. Count sections.
- const char* P1 = P;
- unsigned int est_out = 0;
- while (P1 < End)
- {
- // read next offset
- uint16_t ofs = *((uint16_t*)P1);
- AI_SWAP2(ofs); P1 += 2;
-
- if (ofs >= MSZIP_BLOCK)
- throw DeadlyImportError("X: Invalid offset to next MSZIP compressed block");
-
- // check magic word
- uint16_t magic = *((uint16_t*)P1);
- AI_SWAP2(magic); P1 += 2;
-
- if (magic != MSZIP_MAGIC)
- throw DeadlyImportError("X: Unsupported compressed format, expected MSZIP header");
-
- // and advance to the next offset
- P1 += ofs;
- est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
- }
-
- // Allocate storage and do the actual uncompressing
- uncompressed.resize(est_out);
- char* out = &uncompressed.front();
- while (P < End)
- {
- uint16_t ofs = *((uint16_t*)P);
- AI_SWAP2(ofs);
- P += 4;
-
- // push data to the stream
- stream.next_in = (Bytef*)P;
- stream.avail_in = ofs;
- stream.next_out = (Bytef*)out;
- stream.avail_out = MSZIP_BLOCK;
-
- // and decompress the data ....
- int ret = ::inflate( &stream, Z_SYNC_FLUSH );
- if (ret != Z_OK && ret != Z_STREAM_END)
- throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
-
- ::inflateReset( &stream );
- ::inflateSetDictionary( &stream, (const Bytef*)out , MSZIP_BLOCK - stream.avail_out );
-
- // and advance to the next offset
- out += MSZIP_BLOCK - stream.avail_out;
- P += ofs;
- }
-
- // terminate zlib
- ::inflateEnd(&stream);
-
- // ok, update pointers to point to the uncompressed file data
- P = &uncompressed[0];
- End = out;
-
- // FIXME: we don't need the compressed data anymore, could release
- // it already for better memory usage. Consider breaking const-co.
- DefaultLogger::get()->info("Successfully decompressed MSZIP-compressed file");
-#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
- }
- else
- {
- // start reading here
- ReadUntilEndOfLine();
- }
-
- mScene = new Scene;
- ParseFile();
-
- // filter the imported hierarchy for some degenerated cases
- if ( mScene->mRootNode) {
- FilterHierarchy( mScene->mRootNode);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor. Destroys all imported data along with it
-XFileParser::~XFileParser()
-{
- // kill everything we created
- delete mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseFile()
-{
- bool running = true;
- while ( running )
- {
- // read name of next object
- std::string objectName = GetNextToken();
- if (objectName.length() == 0)
- break;
-
- // parse specific object
- if ( objectName == "template")
- ParseDataObjectTemplate();
- else
- if ( objectName == "Frame")
- ParseDataObjectFrame( NULL);
- else
- if ( objectName == "Mesh")
- {
- // some meshes have no frames at all
- Mesh* mesh = new Mesh;
- ParseDataObjectMesh( mesh);
- mScene->mGlobalMeshes.push_back( mesh);
- } else
- if ( objectName == "AnimTicksPerSecond")
- ParseDataObjectAnimTicksPerSecond();
- else
- if ( objectName == "AnimationSet")
- ParseDataObjectAnimationSet();
- else
- if ( objectName == "Material")
- {
- // Material outside of a mesh or node
- Material material;
- ParseDataObjectMaterial( &material);
- mScene->mGlobalMaterials.push_back( material);
- } else
- if ( objectName == "}")
- {
- // whatever?
- DefaultLogger::get()->warn("} found in dataObject");
- } else
- {
- // unknown format
- DefaultLogger::get()->warn("Unknown data object in animation of .x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTemplate()
-{
- // parse a template data object. Currently not stored.
- std::string name;
- readHeadOfDataObject( &name);
-
- // read GUID
- std::string guid = GetNextToken();
-
- // read and ignore data members
- bool running = true;
- while ( running )
- {
- std::string s = GetNextToken();
-
- if ( s == "}")
- break;
-
- if ( s.length() == 0)
- ThrowException( "Unexpected end of file reached while parsing template definition");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectFrame( Node* pParent)
-{
- // A coordinate frame, or "frame of reference." The Frame template
- // is open and can contain any object. The Direct3D extensions (D3DX)
- // mesh-loading functions recognize Mesh, FrameTransformMatrix, and
- // Frame template instances as child objects when loading a Frame
- // instance.
- std::string name;
- readHeadOfDataObject(&name);
-
- // create a named node and place it at its parent, if given
- Node* node = new Node( pParent);
- node->mName = name;
- if ( pParent)
- {
- pParent->mChildren.push_back( node);
- } else
- {
- // there might be multiple root nodes
- if ( mScene->mRootNode != NULL)
- {
- // place a dummy root if not there
- if ( mScene->mRootNode->mName != "$dummy_root")
- {
- Node* exroot = mScene->mRootNode;
- mScene->mRootNode = new Node( NULL);
- mScene->mRootNode->mName = "$dummy_root";
- mScene->mRootNode->mChildren.push_back( exroot);
- exroot->mParent = mScene->mRootNode;
- }
- // put the new node as its child instead
- mScene->mRootNode->mChildren.push_back( node);
- node->mParent = mScene->mRootNode;
- } else
- {
- // it's the first node imported. place it as root
- mScene->mRootNode = node;
- }
- }
-
- // Now inside a frame.
- // read tokens until closing brace is reached.
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if (objectName.size() == 0)
- ThrowException( "Unexpected end of file reached while parsing frame");
-
- if ( objectName == "}")
- break; // frame finished
- else
- if ( objectName == "Frame")
- ParseDataObjectFrame( node); // child frame
- else
- if ( objectName == "FrameTransformMatrix")
- ParseDataObjectTransformationMatrix( node->mTrafoMatrix);
- else
- if ( objectName == "Mesh")
- {
- Mesh* mesh = new Mesh;
- node->mMeshes.push_back( mesh);
- ParseDataObjectMesh( mesh);
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in frame in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix)
-{
- // read header, we're not interested if it has a name
- readHeadOfDataObject();
-
- // read its components
- pMatrix.a1 = ReadFloat(); pMatrix.b1 = ReadFloat();
- pMatrix.c1 = ReadFloat(); pMatrix.d1 = ReadFloat();
- pMatrix.a2 = ReadFloat(); pMatrix.b2 = ReadFloat();
- pMatrix.c2 = ReadFloat(); pMatrix.d2 = ReadFloat();
- pMatrix.a3 = ReadFloat(); pMatrix.b3 = ReadFloat();
- pMatrix.c3 = ReadFloat(); pMatrix.d3 = ReadFloat();
- pMatrix.a4 = ReadFloat(); pMatrix.b4 = ReadFloat();
- pMatrix.c4 = ReadFloat(); pMatrix.d4 = ReadFloat();
-
- // trailing symbols
- CheckForSemicolon();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
-{
- std::string name;
- readHeadOfDataObject( &name);
-
- // read vertex count
- unsigned int numVertices = ReadInt();
- pMesh->mPositions.resize( numVertices);
-
- // read vertices
- for ( unsigned int a = 0; a < numVertices; a++)
- pMesh->mPositions[a] = ReadVector3();
-
- // read position faces
- unsigned int numPosFaces = ReadInt();
- pMesh->mPosFaces.resize( numPosFaces);
- for ( unsigned int a = 0; a < numPosFaces; a++)
- {
- unsigned int numIndices = ReadInt();
- if ( numIndices < 3)
- ThrowException( boost::str( boost::format( "Invalid index count %1% for face %2%.") % numIndices % a));
-
- // read indices
- Face& face = pMesh->mPosFaces[a];
- for ( unsigned int b = 0; b < numIndices; b++)
- face.mIndices.push_back( ReadInt());
- CheckForSeparator();
- }
-
- // here, other data objects may follow
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
-
- if ( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh structure");
- else
- if ( objectName == "}")
- break; // mesh finished
- else
- if ( objectName == "MeshNormals")
- ParseDataObjectMeshNormals( pMesh);
- else
- if ( objectName == "MeshTextureCoords")
- ParseDataObjectMeshTextureCoords( pMesh);
- else
- if ( objectName == "MeshVertexColors")
- ParseDataObjectMeshVertexColors( pMesh);
- else
- if ( objectName == "MeshMaterialList")
- ParseDataObjectMeshMaterialList( pMesh);
- else
- if ( objectName == "VertexDuplicationIndices")
- ParseUnknownDataObject(); // we'll ignore vertex duplication indices
- else
- if ( objectName == "XSkinMeshHeader")
- ParseDataObjectSkinMeshHeader( pMesh);
- else
- if ( objectName == "SkinWeights")
- ParseDataObjectSkinWeights( pMesh);
- else
- {
- DefaultLogger::get()->warn("Unknown data object in mesh in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectSkinWeights( Mesh *pMesh)
-{
- readHeadOfDataObject();
-
- std::string transformNodeName;
- GetNextTokenAsString( transformNodeName);
-
- pMesh->mBones.push_back( Bone());
- Bone& bone = pMesh->mBones.back();
- bone.mName = transformNodeName;
-
- // read vertex weights
- unsigned int numWeights = ReadInt();
- bone.mWeights.reserve( numWeights);
-
- for ( unsigned int a = 0; a < numWeights; a++)
- {
- BoneWeight weight;
- weight.mVertex = ReadInt();
- bone.mWeights.push_back( weight);
- }
-
- // read vertex weights
- for ( unsigned int a = 0; a < numWeights; a++)
- bone.mWeights[a].mWeight = ReadFloat();
-
- // read matrix offset
- bone.mOffsetMatrix.a1 = ReadFloat(); bone.mOffsetMatrix.b1 = ReadFloat();
- bone.mOffsetMatrix.c1 = ReadFloat(); bone.mOffsetMatrix.d1 = ReadFloat();
- bone.mOffsetMatrix.a2 = ReadFloat(); bone.mOffsetMatrix.b2 = ReadFloat();
- bone.mOffsetMatrix.c2 = ReadFloat(); bone.mOffsetMatrix.d2 = ReadFloat();
- bone.mOffsetMatrix.a3 = ReadFloat(); bone.mOffsetMatrix.b3 = ReadFloat();
- bone.mOffsetMatrix.c3 = ReadFloat(); bone.mOffsetMatrix.d3 = ReadFloat();
- bone.mOffsetMatrix.a4 = ReadFloat(); bone.mOffsetMatrix.b4 = ReadFloat();
- bone.mOffsetMatrix.c4 = ReadFloat(); bone.mOffsetMatrix.d4 = ReadFloat();
-
- CheckForSemicolon();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectSkinMeshHeader( Mesh* /*pMesh*/ )
-{
- readHeadOfDataObject();
-
- /*unsigned int maxSkinWeightsPerVertex =*/ ReadInt();
- /*unsigned int maxSkinWeightsPerFace =*/ ReadInt();
- /*unsigned int numBonesInMesh = */ReadInt();
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
-{
- readHeadOfDataObject();
-
- // read count
- unsigned int numNormals = ReadInt();
- pMesh->mNormals.resize( numNormals);
-
- // read normal vectors
- for ( unsigned int a = 0; a < numNormals; a++)
- pMesh->mNormals[a] = ReadVector3();
-
- // read normal indices
- unsigned int numFaces = ReadInt();
- if ( numFaces != pMesh->mPosFaces.size())
- ThrowException( "Normal face count does not match vertex face count.");
-
- for ( unsigned int a = 0; a < numFaces; a++)
- {
- unsigned int numIndices = ReadInt();
- pMesh->mNormFaces.push_back( Face());
- Face& face = pMesh->mNormFaces.back();
-
- for ( unsigned int b = 0; b < numIndices; b++)
- face.mIndices.push_back( ReadInt());
-
- CheckForSeparator();
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
-{
- readHeadOfDataObject();
- std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++];
-
- unsigned int numCoords = ReadInt();
- if ( numCoords != pMesh->mPositions.size())
- ThrowException( "Texture coord count does not match vertex count");
-
- coords.resize( numCoords);
- for ( unsigned int a = 0; a < numCoords; a++)
- coords[a] = ReadVector2();
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
-{
- readHeadOfDataObject();
- std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
-
- unsigned int numColors = ReadInt();
- if ( numColors != pMesh->mPositions.size())
- ThrowException( "Vertex color count does not match vertex count");
-
- colors.resize( numColors, aiColor4D( 0, 0, 0, 1));
- for ( unsigned int a = 0; a < numColors; a++)
- {
- unsigned int index = ReadInt();
- if ( index >= pMesh->mPositions.size())
- ThrowException( "Vertex color index out of bounds");
-
- colors[index] = ReadRGBA();
- // HACK: (thom) Maxon Cinema XPort plugin puts a third separator here, kwxPort puts a comma.
- // Ignore gracefully.
- if ( !mIsBinaryFormat)
- {
- FindNextNoneWhiteSpace();
- if ( *P == ';' || *P == ',')
- P++;
- }
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
-{
- readHeadOfDataObject();
-
- // read material count
- /*unsigned int numMaterials =*/ ReadInt();
- // read non triangulated face material index count
- unsigned int numMatIndices = ReadInt();
-
- // some models have a material index count of 1... to be able to read them we
- // replicate this single material index on every face
- if ( numMatIndices != pMesh->mPosFaces.size() && numMatIndices != 1)
- ThrowException( "Per-Face material index count does not match face count.");
-
- // read per-face material indices
- for ( unsigned int a = 0; a < numMatIndices; a++)
- pMesh->mFaceMaterials.push_back( ReadInt());
-
- // in version 03.02, the face indices end with two semicolons.
- // commented out version check, as version 03.03 exported from blender also has 2 semicolons
- if ( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
- {
- if ( *P == ';')
- ++P;
- }
-
- // if there was only a single material index, replicate it on all faces
- while ( pMesh->mFaceMaterials.size() < pMesh->mPosFaces.size())
- pMesh->mFaceMaterials.push_back( pMesh->mFaceMaterials.front());
-
- // read following data objects
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if ( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh material list.");
- else
- if ( objectName == "}")
- break; // material list finished
- else
- if ( objectName == "{")
- {
- // template materials
- std::string matName = GetNextToken();
- Material material;
- material.mIsReference = true;
- material.mName = matName;
- pMesh->mMaterials.push_back( material);
-
- CheckForClosingBrace(); // skip }
- } else
- if ( objectName == "Material")
- {
- pMesh->mMaterials.push_back( Material());
- ParseDataObjectMaterial( &pMesh->mMaterials.back());
- } else
- if ( objectName == ";")
- {
- // ignore
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in material list in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
-{
- std::string matName;
- readHeadOfDataObject( &matName);
- if ( matName.empty())
- matName = std::string( "material") + boost::lexical_cast<std::string>( mLineNumber);
- pMaterial->mName = matName;
- pMaterial->mIsReference = false;
-
- // read material values
- pMaterial->mDiffuse = ReadRGBA();
- pMaterial->mSpecularExponent = ReadFloat();
- pMaterial->mSpecular = ReadRGB();
- pMaterial->mEmissive = ReadRGB();
-
- // read other data objects
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if ( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh material");
- else
- if ( objectName == "}")
- break; // material finished
- else
- if ( objectName == "TextureFilename" || objectName == "TextureFileName")
- {
- // some exporters write "TextureFileName" instead.
- std::string texname;
- ParseDataObjectTextureFilename( texname);
- pMaterial->mTextures.push_back( TexEntry( texname));
- } else
- if ( objectName == "NormalmapFilename" || objectName == "NormalmapFileName")
- {
- // one exporter writes out the normal map in a separate filename tag
- std::string texname;
- ParseDataObjectTextureFilename( texname);
- pMaterial->mTextures.push_back( TexEntry( texname, true));
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in material in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimTicksPerSecond()
-{
- readHeadOfDataObject();
- mScene->mAnimTicksPerSecond = ReadInt();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimationSet()
-{
- std::string animName;
- readHeadOfDataObject( &animName);
-
- Animation* anim = new Animation;
- mScene->mAnims.push_back( anim);
- anim->mName = animName;
-
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if ( objectName.length() == 0)
- ThrowException( "Unexpected end of file while parsing animation set.");
- else
- if ( objectName == "}")
- break; // animation set finished
- else
- if ( objectName == "Animation")
- ParseDataObjectAnimation( anim);
- else
- {
- DefaultLogger::get()->warn("Unknown data object in animation set in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimation( Animation* pAnim)
-{
- readHeadOfDataObject();
- AnimBone* banim = new AnimBone;
- pAnim->mAnims.push_back( banim);
-
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
-
- if ( objectName.length() == 0)
- ThrowException( "Unexpected end of file while parsing animation.");
- else
- if ( objectName == "}")
- break; // animation finished
- else
- if ( objectName == "AnimationKey")
- ParseDataObjectAnimationKey( banim);
- else
- if ( objectName == "AnimationOptions")
- ParseUnknownDataObject(); // not interested
- else
- if ( objectName == "{")
- {
- // read frame name
- banim->mBoneName = GetNextToken();
- CheckForClosingBrace();
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in animation in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimationKey( AnimBone* pAnimBone)
-{
- readHeadOfDataObject();
-
- // read key type
- unsigned int keyType = ReadInt();
-
- // read number of keys
- unsigned int numKeys = ReadInt();
-
- for ( unsigned int a = 0; a < numKeys; a++)
- {
- // read time
- unsigned int time = ReadInt();
-
- // read keys
- switch( keyType)
- {
- case 0: // rotation quaternion
- {
- // read count
- if ( ReadInt() != 4)
- ThrowException( "Invalid number of arguments for quaternion key in animation");
-
- aiQuatKey key;
- key.mTime = double( time);
- key.mValue.w = ReadFloat();
- key.mValue.x = ReadFloat();
- key.mValue.y = ReadFloat();
- key.mValue.z = ReadFloat();
- pAnimBone->mRotKeys.push_back( key);
-
- CheckForSemicolon();
- break;
- }
-
- case 1: // scale vector
- case 2: // position vector
- {
- // read count
- if ( ReadInt() != 3)
- ThrowException( "Invalid number of arguments for vector key in animation");
-
- aiVectorKey key;
- key.mTime = double( time);
- key.mValue = ReadVector3();
-
- if ( keyType == 2)
- pAnimBone->mPosKeys.push_back( key);
- else
- pAnimBone->mScaleKeys.push_back( key);
-
- break;
- }
-
- case 3: // combined transformation matrix
- case 4: // denoted both as 3 or as 4
- {
- // read count
- if ( ReadInt() != 16)
- ThrowException( "Invalid number of arguments for matrix key in animation");
-
- // read matrix
- MatrixKey key;
- key.mTime = double( time);
- key.mMatrix.a1 = ReadFloat(); key.mMatrix.b1 = ReadFloat();
- key.mMatrix.c1 = ReadFloat(); key.mMatrix.d1 = ReadFloat();
- key.mMatrix.a2 = ReadFloat(); key.mMatrix.b2 = ReadFloat();
- key.mMatrix.c2 = ReadFloat(); key.mMatrix.d2 = ReadFloat();
- key.mMatrix.a3 = ReadFloat(); key.mMatrix.b3 = ReadFloat();
- key.mMatrix.c3 = ReadFloat(); key.mMatrix.d3 = ReadFloat();
- key.mMatrix.a4 = ReadFloat(); key.mMatrix.b4 = ReadFloat();
- key.mMatrix.c4 = ReadFloat(); key.mMatrix.d4 = ReadFloat();
- pAnimBone->mTrafoKeys.push_back( key);
-
- CheckForSemicolon();
- break;
- }
-
- default:
- ThrowException( boost::str( boost::format( "Unknown key type %1% in animation.") % keyType));
- break;
- } // end switch
-
- // key separator
- CheckForSeparator();
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTextureFilename( std::string& pName)
-{
- readHeadOfDataObject();
- GetNextTokenAsString( pName);
- CheckForClosingBrace();
-
- // FIX: some files (e.g. AnimationTest.x) have "" as texture file name
- if (!pName.length())
- {
- DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
- }
-
- // some exporters write double backslash paths out. We simply replace them if we find them
- while ( pName.find( "\\\\") != std::string::npos)
- pName.replace( pName.find( "\\\\"), 2, "\\");
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseUnknownDataObject()
-{
- // find opening delimiter
- bool running = true;
- while ( running )
- {
- std::string t = GetNextToken();
- if ( t.length() == 0)
- ThrowException( "Unexpected end of file while parsing unknown segment.");
-
- if ( t == "{")
- break;
- }
-
- unsigned int counter = 1;
-
- // parse until closing delimiter
- while ( counter > 0)
- {
- std::string t = GetNextToken();
-
- if ( t.length() == 0)
- ThrowException( "Unexpected end of file while parsing unknown segment.");
-
- if ( t == "{")
- ++counter;
- else
- if ( t == "}")
- --counter;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for closing curly brace
-void XFileParser::CheckForClosingBrace()
-{
- if ( GetNextToken() != "}")
- ThrowException( "Closing brace expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for one following semicolon
-void XFileParser::CheckForSemicolon()
-{
- if ( mIsBinaryFormat)
- return;
-
- if ( GetNextToken() != ";")
- ThrowException( "Semicolon expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for a separator char, either a ',' or a ';'
-void XFileParser::CheckForSeparator()
-{
- if ( mIsBinaryFormat)
- return;
-
- std::string token = GetNextToken();
- if ( token != "," && token != ";")
- ThrowException( "Separator character (';' or ',') expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// tests and possibly consumes a separator char, but does nothing if there was no separator
-void XFileParser::TestForSeparator()
-{
- if ( mIsBinaryFormat)
- return;
-
- FindNextNoneWhiteSpace();
- if ( P >= End)
- return;
-
- // test and skip
- if ( *P == ';' || *P == ',')
- P++;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::readHeadOfDataObject( std::string* poName)
-{
- std::string nameOrBrace = GetNextToken();
- if ( nameOrBrace != "{")
- {
- if ( poName)
- *poName = nameOrBrace;
-
- if ( GetNextToken() != "{")
- ThrowException( "Opening brace expected.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string XFileParser::GetNextToken()
-{
- std::string s;
-
- // process binary-formatted file
- if ( mIsBinaryFormat)
- {
- // in binary mode it will only return NAME and STRING token
- // and (correctly) skip over other tokens.
-
- unsigned int tok = ReadBinWord();
- unsigned int len;
-
- // standalone tokens
- switch( tok)
- {
- case 1:
- // name token
- len = ReadBinDWord();
- s = std::string(P, len);
- P += len;
- return s;
- case 2:
- // string token
- len = ReadBinDWord();
- s = std::string(P, len);
- P += (len + 2);
- return s;
- case 3:
- // integer token
- P += 4;
- return "<integer>";
- case 5:
- // GUID token
- P += 16;
- return "<guid>";
- case 6:
- len = ReadBinDWord();
- P += (len * 4);
- return "<int_list>";
- case 7:
- len = ReadBinDWord();
- P += (len * mBinaryFloatSize);
- return "<flt_list>";
- case 0x0a:
- return "{";
- case 0x0b:
- return "}";
- case 0x0c:
- return "(";
- case 0x0d:
- return ")";
- case 0x0e:
- return "[";
- case 0x0f:
- return "]";
- case 0x10:
- return "<";
- case 0x11:
- return ">";
- case 0x12:
- return ".";
- case 0x13:
- return ",";
- case 0x14:
- return ";";
- case 0x1f:
- return "template";
- case 0x28:
- return "WORD";
- case 0x29:
- return "DWORD";
- case 0x2a:
- return "FLOAT";
- case 0x2b:
- return "DOUBLE";
- case 0x2c:
- return "CHAR";
- case 0x2d:
- return "UCHAR";
- case 0x2e:
- return "SWORD";
- case 0x2f:
- return "SDWORD";
- case 0x30:
- return "void";
- case 0x31:
- return "string";
- case 0x32:
- return "unicode";
- case 0x33:
- return "cstring";
- case 0x34:
- return "array";
- }
- }
- // process text-formatted file
- else
- {
- FindNextNoneWhiteSpace();
- if ( P >= End)
- return s;
-
- while ( (P < End) && !isspace( (unsigned char) *P))
- {
- // either keep token delimiters when already holding a token, or return if first valid char
- if ( *P == ';' || *P == '}' || *P == '{' || *P == ',')
- {
- if ( !s.size())
- s.append( P++, 1);
- break; // stop for delimiter
- }
- s.append( P++, 1);
- }
- }
- return s;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::FindNextNoneWhiteSpace()
-{
- if ( mIsBinaryFormat)
- return;
-
- bool running = true;
- while ( running )
- {
- while ( P < End && isspace( (unsigned char) *P))
- {
- if ( *P == '\n')
- mLineNumber++;
- ++P;
- }
-
- if ( P >= End)
- return;
-
- // check if this is a comment
- if ( (P[0] == '/' && P[1] == '/') || P[0] == '#')
- ReadUntilEndOfLine();
- else
- break;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::GetNextTokenAsString( std::string& poString)
-{
- if ( mIsBinaryFormat)
- {
- poString = GetNextToken();
- return;
- }
-
- FindNextNoneWhiteSpace();
- if ( P >= End)
- ThrowException( "Unexpected end of file while parsing string");
-
- if ( *P != '"')
- ThrowException( "Expected quotation mark.");
- ++P;
-
- while ( P < End && *P != '"')
- poString.append( P++, 1);
-
- if ( P >= End-1)
- ThrowException( "Unexpected end of file while parsing string");
-
- if ( P[1] != ';' || P[0] != '"')
- ThrowException( "Expected quotation mark and semicolon at the end of a string.");
- P+=2;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ReadUntilEndOfLine()
-{
- if ( mIsBinaryFormat)
- return;
-
- while ( P < End)
- {
- if ( *P == '\n' || *P == '\r')
- {
- ++P; mLineNumber++;
- return;
- }
-
- ++P;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned short XFileParser::ReadBinWord()
-{
- const unsigned char* q = (const unsigned char*) P;
- unsigned short tmp = q[0] | (q[1] << 8);
- P += 2;
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XFileParser::ReadBinDWord()
-{
- const unsigned char* q = (const unsigned char*) P;
- unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
- P += 4;
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XFileParser::ReadInt()
-{
- if ( mIsBinaryFormat)
- {
- if ( mBinaryNumCount == 0)
- {
- unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
- if ( tmp == 0x06) // array of ints follows
- mBinaryNumCount = ReadBinDWord();
- else // single int follows
- mBinaryNumCount = 1;
- }
-
- --mBinaryNumCount;
- return ReadBinDWord();
- } else
- {
- FindNextNoneWhiteSpace();
-
- // TODO: consider using strtol10s instead???
-
- // check preceeding minus sign
- bool isNegative = false;
- if ( *P == '-')
- {
- isNegative = true;
- P++;
- }
-
- // at least one digit expected
- if ( !isdigit( *P))
- ThrowException( "Number expected.");
-
- // read digits
- unsigned int number = 0;
- while ( P < End)
- {
- if ( !isdigit( *P))
- break;
- number = number * 10 + (*P - 48);
- P++;
- }
-
- CheckForSeparator();
- return isNegative ? ((unsigned int) -int( number)) : number;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-float XFileParser::ReadFloat()
-{
- if ( mIsBinaryFormat)
- {
- if ( mBinaryNumCount == 0)
- {
- unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
- if ( tmp == 0x07) // array of floats following
- mBinaryNumCount = ReadBinDWord();
- else // single float following
- mBinaryNumCount = 1;
- }
-
- --mBinaryNumCount;
- if ( mBinaryFloatSize == 8)
- {
- float result = (float) (*(double*) P);
- P += 8;
- return result;
- } else
- {
- float result = *(float*) P;
- P += 4;
- return result;
- }
- }
-
- // text version
- FindNextNoneWhiteSpace();
- // check for various special strings to allow reading files from faulty exporters
- // I mean you, Blender!
- if ( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
- {
- P += 9;
- CheckForSeparator();
- return 0.0f;
- } else
- if ( strncmp( P, "1.#QNAN0", 8) == 0)
- {
- P += 8;
- CheckForSeparator();
- return 0.0f;
- }
-
- float result = 0.0f;
- P = fast_atof_move( P, result);
-
- CheckForSeparator();
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector2D XFileParser::ReadVector2()
-{
- aiVector2D vector;
- vector.x = ReadFloat();
- vector.y = ReadFloat();
- TestForSeparator();
-
- return vector;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector3D XFileParser::ReadVector3()
-{
- aiVector3D vector;
- vector.x = ReadFloat();
- vector.y = ReadFloat();
- vector.z = ReadFloat();
- TestForSeparator();
-
- return vector;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiColor4D XFileParser::ReadRGBA()
-{
- aiColor4D color;
- color.r = ReadFloat();
- color.g = ReadFloat();
- color.b = ReadFloat();
- color.a = ReadFloat();
- TestForSeparator();
-
- return color;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiColor3D XFileParser::ReadRGB()
-{
- aiColor3D color;
- color.r = ReadFloat();
- color.g = ReadFloat();
- color.b = ReadFloat();
- TestForSeparator();
-
- return color;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Throws an exception with a line number and the given text.
-void XFileParser::ThrowException( const std::string& pText)
-{
- if ( mIsBinaryFormat)
- throw DeadlyImportError( pText);
- else
- throw DeadlyImportError( boost::str( boost::format( "Line %d: %s") % mLineNumber % pText));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Filters the imported hierarchy for some degenerated cases that some exporters produce.
-void XFileParser::FilterHierarchy( XFile::Node* pNode)
-{
- // if the node has just a single unnamed child containing a mesh, remove
- // the anonymous node inbetween. The 3DSMax kwXport plugin seems to produce this
- // mess in some cases
- if ( pNode->mChildren.size() == 1)
- {
- XFile::Node* child = pNode->mChildren.front();
- if ( child->mName.length() == 0 && child->mMeshes.size() > 0)
- {
- // transfer its meshes to us
- for ( unsigned int a = 0; a < child->mMeshes.size(); a++)
- pNode->mMeshes.push_back( child->mMeshes[a]);
- child->mMeshes.clear();
-
- // then kill it
- delete child;
- pNode->mChildren.clear();
- }
- }
-
- // recurse
- for ( unsigned int a = 0; a < pNode->mChildren.size(); a++)
- FilterHierarchy( pNode->mChildren[a]);
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
diff --git a/3rdparty/assimp/code/XFileParser.h b/3rdparty/assimp/code/XFileParser.h
deleted file mode 100644
index 8000c133..00000000
--- a/3rdparty/assimp/code/XFileParser.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file Helper class to parse a XFile into a temporary structure */
-#ifndef AI_XFILEPARSER_H_INC
-#define AI_XFILEPARSER_H_INC
-
-#include <string>
-#include <vector>
-
-#include "../include/aiTypes.h"
-
-namespace Assimp
-{
- namespace XFile
- {
- struct Node;
- struct Mesh;
- struct Scene;
- struct Material;
- struct Animation;
- struct AnimBone;
- }
-
-/** The XFileParser reads a XFile either in text or binary form and builds a temporary
- * data structure out of it.
- */
-class XFileParser
-{
-public:
- /** Constructor. Creates a data structure out of the XFile given in the memory block.
- * @param pBuffer Memory buffer containing the XFile
- */
- XFileParser( const std::vector<char>& pBuffer);
-
- /** Destructor. Destroys all imported data along with it */
- ~XFileParser();
-
- /** Returns the temporary representation of the imported data */
- const XFile::Scene* GetImportedData() const { return mScene; }
-
-protected:
- void ParseFile();
- void ParseDataObjectTemplate();
- void ParseDataObjectFrame( XFile::Node *pParent);
- void ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix);
- void ParseDataObjectMesh( XFile::Mesh* pMesh);
- void ParseDataObjectSkinWeights( XFile::Mesh* pMesh);
- void ParseDataObjectSkinMeshHeader( XFile::Mesh* pMesh);
- void ParseDataObjectMeshNormals( XFile::Mesh* pMesh);
- void ParseDataObjectMeshTextureCoords( XFile::Mesh* pMesh);
- void ParseDataObjectMeshVertexColors( XFile::Mesh* pMesh);
- void ParseDataObjectMeshMaterialList( XFile::Mesh* pMesh);
- void ParseDataObjectMaterial( XFile::Material* pMaterial);
- void ParseDataObjectAnimTicksPerSecond();
- void ParseDataObjectAnimationSet();
- void ParseDataObjectAnimation( XFile::Animation* pAnim);
- void ParseDataObjectAnimationKey( XFile::AnimBone *pAnimBone);
- void ParseDataObjectTextureFilename( std::string& pName);
- void ParseUnknownDataObject();
-
- //! places pointer to next begin of a token, and ignores comments
- void FindNextNoneWhiteSpace();
-
- //! returns next parseable token. Returns empty string if no token there
- std::string GetNextToken();
-
- //! reads header of dataobject including the opening brace.
- //! returns false if error happened, and writes name of object
- //! if there is one
- void readHeadOfDataObject( std::string* poName = NULL);
-
- //! checks for closing curly brace, throws exception if not there
- void CheckForClosingBrace();
-
- //! checks for one following semicolon, throws exception if not there
- void CheckForSemicolon();
-
- //! checks for a separator char, either a ',' or a ';'
- void CheckForSeparator();
-
- /// tests and possibly consumes a separator char, but does nothing if there was no separator
- void TestForSeparator();
-
- //! reads a x file style string
- void GetNextTokenAsString( std::string& poString);
-
- void ReadUntilEndOfLine();
-
- unsigned short ReadBinWord();
- unsigned int ReadBinDWord();
- unsigned int ReadInt();
- float ReadFloat();
- aiVector2D ReadVector2();
- aiVector3D ReadVector3();
- aiColor3D ReadRGB();
- aiColor4D ReadRGBA();
-
- /** Throws an exception with a line number and the given text. */
- void ThrowException( const std::string& pText);
-
- /** Filters the imported hierarchy for some degenerated cases that some exporters produce.
- * @param pData The sub-hierarchy to filter
- */
- void FilterHierarchy( XFile::Node* pNode);
-
-protected:
- unsigned int mMajorVersion, mMinorVersion; ///< version numbers
- bool mIsBinaryFormat; ///< true if the file is in binary, false if it's in text form
- unsigned int mBinaryFloatSize; ///< float size, either 32 or 64 bits
- // counter for number arrays in binary format
- unsigned int mBinaryNumCount;
-
- const char* P;
- const char* End;
-
- /// Line number when reading in text format
- unsigned int mLineNumber;
-
- /// Imported data
- XFile::Scene* mScene;
-};
-
-}
-#endif // AI_XFILEPARSER_H_INC
diff --git a/3rdparty/assimp/code/aiAssert.cpp b/3rdparty/assimp/code/aiAssert.cpp
deleted file mode 100644
index bb0781ba..00000000
--- a/3rdparty/assimp/code/aiAssert.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#include "AssimpPCH.h"
-#include "../include/aiAssert.h"
-#ifdef _WIN32
-#ifndef __GNUC__
-# include "crtdbg.h"
-#endif // ndef gcc
-#endif // _WIN32
-
-// Set a breakpoint using win32, else line, file and message will be returned and progam ends with
-// errrocode = 1
-AI_WONT_RETURN void Assimp::aiAssert (const std::string &message, unsigned int uiLine, const std::string &file)
-{
- // moved expression testing out of the function and into the macro to avoid constructing
- // two std::string on every single ai_assert test
-// if (!expression)
- {
- // FIX (Aramis): changed std::cerr to std::cout that the message appears in VS' output window ...
- std::cout << "File :" << file << ", line " << uiLine << " : " << message << std::endl;
-
-#ifdef _WIN32
-#ifndef __GNUC__
- // Set breakpoint
- __debugbreak();
-#endif //ndef gcc
-#else
- exit (1);
-#endif
- }
-}
diff --git a/3rdparty/assimp/code/assbin_chunks.h b/3rdparty/assimp/code/assbin_chunks.h
deleted file mode 100644
index 5d0a4ed4..00000000
--- a/3rdparty/assimp/code/assbin_chunks.h
+++ /dev/null
@@ -1,196 +0,0 @@
-
-#ifndef INCLUDED_ASSBIN_CHUNKS_H
-#define INCLUDED_ASSBIN_CHUNKS_H
-
-#define ASSBIN_VERSION_MAJOR 1
-#define ASSBIN_VERSION_MINOR 0
-
-/**
-@page assfile .ASS File formats
-
-@section over Overview
-Assimp provides its own interchange format, which is intended to applications which need
-to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to
-be read by Assimp itself. They encode additional information needed by Assimp to optimize
-its postprocessing pipeline. If you once apply specific steps to a scene, then save it
-and reread it from an ASS format using the same post processing settings, they won't
-be executed again.
-
-The format comes in two flavours: XML and binary - both of them hold a complete dump of
-the 'aiScene' data structure returned by the APIs. The focus for the binary format
-(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML
-flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene.
-
-ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt>&lt;root&gt;/tools/assimp_cmd</tt>) is able to
-write it and the core library provides a loader for it.
-
-@section assxml XML File format
-
-The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure.
-With few exceptions, C structures are wrapped in XML elements.
-
-The DTD for ASSXML can be found in <tt>&lt;root&gt;/doc/AssXML_Scheme.xml</tt>. Or have look
-at the output files generated by assimp_cmd.
-
-@section assbin Binary file format
-
-The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure.
-This makes the format extensible and allows backward-compatibility with future data structure
-versions. The <tt>&lt;root&gt;/code/assbin_chunks.h</tt> header contains some magic constants
-for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found
-in <tt>&lt;root&gt;/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...).
-
-@verbatim
-
--------------------------------------------------------------------------------
-1. File structure:
--------------------------------------------------------------------------------
-
-----------------------
-| Header (500 bytes) |
-----------------------
-| Variable chunks |
-----------------------
-
--------------------------------------------------------------------------------
-2. Definitions:
--------------------------------------------------------------------------------
-
-integer is four bytes wide, stored in little-endian byte order.
-short is two bytes wide, stored in little-endian byte order.
-byte is a single byte.
-string is an integer n followed by n UTF-8 characters, not terminated by zero
-float is an IEEE 754 single-precision floating-point value
-double is an IEEE 754 double-precision floating-point value
-t[n] is an array of n elements of type t
-
--------------------------------------------------------------------------------
-2. Header:
--------------------------------------------------------------------------------
-
-byte[44] Magic identification string for ASSBIN files.
- 'ASSIMP.binary'
-
-integer Major version of the Assimp library which wrote the file
-integer Minor version of the Assimp library which wrote the file
- match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR
-
-integer SVN revision of the Assimp library (intended for our internal
- debugging - if you write Ass files from your own APPs, set this value to 0.
-integer Assimp compile flags
-
-short 0 for normal files, 1 for shortened dumps for regression tests
- these should have the file extension assbin.regress
-
-short 1 if the data after the header is compressed with the DEFLATE algorithm,
- 0 for uncompressed files.
- For compressed files, the first integer after the header is
- always the uncompressed data size
-
-byte[256] Zero-terminated source file name, UTF-8
-byte[128] Zero-terminated command line parameters passed to assimp_cmd, UTF-8
-
-byte[64] Reserved for future use
----> Total length: 512 bytes
-
--------------------------------------------------------------------------------
-3. Chunks:
--------------------------------------------------------------------------------
-
-integer Magic chunk ID (ASSBIN_CHUNK_XXX)
-integer Chunk data length, in bytes
- (unknown chunks are possible, a good reader skips over them)
-
-byte[n] length-of-chunk bytes of data, depending on the chunk type
-
-Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk,
-their size is included in length-of-chunk.
-
-The chunk layout for all ASSIMP data structures is derived from their C declarations.
-The general 'rule' to get from Assimp headers to the serialized layout is:
-
- 1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices),
- in order of declaration.
-
- 2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights),
- in order of declaration.
-
- 2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in
- subchunks directly following the data written in 1.) and 2.)
-
-
- Of course, there are some exceptions to this general order:
-
-[[aiScene]]
-
- - The root node holding the scene structure is naturally stored in
- a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is
- empty for aiScene).
-
-[[aiMesh]]
-
- - mTextureCoords and mNumUVComponents are serialized as follows:
-
- [number of used uv channels times]
- integer mNumUVComponents[n]
- float mTextureCoords[n][mNumUVComponents[n]]
-
- -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp
- builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange
- data. Unlike the in-memory format, only the used components of the
- UV coordinates are written to disk. If mNumUVComponents[0] is 1, the
- corresponding mTextureCoords array consists of mNumTextureCoords*1
- single floats.
-
- - The array member block of aiMesh is prefixed with an integer that specifies
- the kinds of vertex components actually present in the mesh. This is a
- bitwise combination of the ASSBIN_MESH_HAS_xxx constants.
-
-[[aiFace]]
-
- - mNumIndices is stored as short
- - mIndices are written as short, if aiMesh::mNumVertices<65536
-
-[[aiNode]]
-
- - mParent is ommitted
-
-[[aiLight]]
-
- - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL
- - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT
-
-[[aiMaterial]]
-
- - mNumAllocated is ommitted, for obvious reasons :-)
-
-
- @endverbatim*/
-
-
-#define ASSBIN_HEADER_LENGTH 512
-
-// these are the magic chunk identifiers for the binary ASS file format
-#define ASSBIN_CHUNK_AICAMERA 0x1234
-#define ASSBIN_CHUNK_AILIGHT 0x1235
-#define ASSBIN_CHUNK_AITEXTURE 0x1236
-#define ASSBIN_CHUNK_AIMESH 0x1237
-#define ASSBIN_CHUNK_AINODEANIM 0x1238
-#define ASSBIN_CHUNK_AISCENE 0x1239
-#define ASSBIN_CHUNK_AIBONE 0x123a
-#define ASSBIN_CHUNK_AIANIMATION 0x123b
-#define ASSBIN_CHUNK_AINODE 0x123c
-#define ASSBIN_CHUNK_AIMATERIAL 0x123d
-#define ASSBIN_CHUNK_AIMATERIALPROPERTY 0x123e
-
-#define ASSBIN_MESH_HAS_POSITIONS 0x1
-#define ASSBIN_MESH_HAS_NORMALS 0x2
-#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS 0x4
-#define ASSBIN_MESH_HAS_TEXCOORD_BASE 0x100
-#define ASSBIN_MESH_HAS_COLOR_BASE 0x10000
-
-#define ASSBIN_MESH_HAS_TEXCOORD(n) (ASSBIN_MESH_HAS_TEXCOORD_BASE << n)
-#define ASSBIN_MESH_HAS_COLOR(n) (ASSBIN_MESH_HAS_COLOR_BASE << n)
-
-
-#endif // INCLUDED_ASSBIN_CHUNKS_H
diff --git a/3rdparty/assimp/code/fast_atof.h b/3rdparty/assimp/code/fast_atof.h
deleted file mode 100644
index 6b242afc..00000000
--- a/3rdparty/assimp/code/fast_atof.h
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright (C) 2002-2007 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
-
-// ------------------------------------------------------------------------------------
-// Original description: (Schrompf)
-// Adapted to the ASSIMP library because the builtin atof indeed takes AGES to parse a
-// float inside a large string. Before parsing, it does a strlen on the given point.
-// Changes:
-// 22nd October 08 (Aramis_acg): Added temporary cast to double, added strtol10_64
-// to ensure long numbers are handled correctly
-// ------------------------------------------------------------------------------------
-
-
-#ifndef __FAST_A_TO_F_H_INCLUDED__
-#define __FAST_A_TO_F_H_INCLUDED__
-
-#include <math.h>
-
-namespace Assimp
-{
-
-const float fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug
- 0.f,
- 0.1f,
- 0.01f,
- 0.001f,
- 0.0001f,
- 0.00001f,
- 0.000001f,
- 0.0000001f,
- 0.00000001f,
- 0.000000001f,
- 0.0000000001f,
- 0.00000000001f,
- 0.000000000001f,
- 0.0000000000001f,
- 0.00000000000001f,
- 0.000000000000001f
-};
-
-
-// ------------------------------------------------------------------------------------
-// Convert a string in decimal format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtol10( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in < '0' || *in > '9' )
- break;
-
- value = ( value * 10 ) + ( *in - '0' );
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a string in octal format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtol8( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in < '0' || *in > '7' )
- break;
-
- value = ( value << 3 ) + ( *in - '0' );
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a string in hex format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtol16( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in >= '0' && *in <= '9' )
- {
- value = ( value << 4u ) + ( *in - '0' );
- }
- else if (*in >= 'A' && *in <= 'F')
- {
- value = ( value << 4u ) + ( *in - 'A' ) + 10;
- }
- else if (*in >= 'a' && *in <= 'f')
- {
- value = ( value << 4u ) + ( *in - 'a' ) + 10;
- }
- else break;
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert just one hex digit
-// Return value is 0xffffffff if the input is not hex
-// ------------------------------------------------------------------------------------
-inline unsigned int HexDigitToDecimal(char in)
-{
- unsigned int out = 0xffffffff;
- if (in >= '0' && in <= '9')
- out = in - '0';
-
- else if (in >= 'a' && in <= 'f')
- out = 10u + in - 'a';
-
- else if (in >= 'A' && in <= 'F')
- out = 10u + in - 'A';
-
- // return value is 0xffffffff if the input is not a hex digit
- return out;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a hex-encoded octet (2 characters processed)
-// Return value is 0xffffffff if the input is not hex
-// ------------------------------------------------------------------------------------
-inline uint8_t HexOctetToDecimal(const char* in)
-{
- return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
-}
-
-
-// ------------------------------------------------------------------------------------
-// signed variant of strtol10
-// ------------------------------------------------------------------------------------
-inline int strtol10s( const char* in, const char** out=0)
-{
- bool inv = (*in=='-');
- if (inv || *in=='+')
- ++in;
-
- int value = strtol10(in,out);
- if (inv) {
- value = -value;
- }
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Parse a C++-like integer literal - hex and oct prefixes.
-// 0xNNNN - hex
-// 0NNN - oct
-// NNN - dec
-// ------------------------------------------------------------------------------------
-inline unsigned int strtol_cppstyle( const char* in, const char** out=0)
-{
- if ('0' == in[0])
- {
- return 'x' == in[1] ? strtol16(in+2,out) : strtol8(in+1,out);
- }
- return strtol10(in, out);
-}
-
-// ------------------------------------------------------------------------------------
-// Special version of the function, providing higher accuracy and safety
-// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
-// ------------------------------------------------------------------------------------
-inline uint64_t strtol10_64( const char* in, const char** out=0, unsigned int* max_inout=0)
-{
- unsigned int cur = 0;
- uint64_t value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in < '0' || *in > '9' )
- break;
-
- const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
-
- if (new_value < value) /* numeric overflow, we rely on you */
- return value;
-
- value = new_value;
-
- ++in;
- ++cur;
-
- if (max_inout && *max_inout == cur) {
-
- if (out) { /* skip to end */
- while (*in >= '0' && *in <= '9')
- ++in;
- *out = in;
- }
-
- return value;
- }
- }
- if (out)
- *out = in;
-
- if (max_inout)
- *max_inout = cur;
-
- return value;
-}
-
-// Number of relevant decimals for floating-point parsing.
-#define AI_FAST_ATOF_RELAVANT_DECIMALS 6
-
-// ------------------------------------------------------------------------------------
-//! Provides a fast function for converting a string into a float,
-//! about 6 times faster than atof in win32.
-// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
-// ------------------------------------------------------------------------------------
-inline const char* fast_atof_move( const char* c, float& out)
-{
- float f;
-
- bool inv = (*c=='-');
- if (inv || *c=='+')
- ++c;
-
- f = (float) strtol10_64 ( c, &c);
- if (*c == '.' || (c[0] == ',' && (c[1] >= '0' || c[1] <= '9'))) // allow for commas, too
- {
- ++c;
-
- // NOTE: The original implementation is highly unaccurate here. The precision of a single
- // IEEE 754 float is not high enough, everything behind the 6th digit tends to be more
- // inaccurate than it would need to be. Casting to double seems to solve the problem.
- // strtol_64 is used to prevent integer overflow.
-
- // Another fix: this tends to become 0 for long numbers if we don't limit the maximum
- // number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between
- // 1 and 15.
- unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS;
- double pl = (double) strtol10_64 ( c, &c, &diff );
-
- pl *= fast_atof_table[diff];
- f += (float)pl;
- }
-
- // A major 'E' must be allowed. Necessary for proper reading of some DXF files.
- // Thanks to Zhao Lei to point out that this if () must be outside the if (*c == '.' ..)
- if (*c == 'e' || *c == 'E')
- {
- ++c;
- bool einv = (*c=='-');
- if (einv || *c=='+')
- ++c;
-
- float exp = (float)strtol10_64(c, &c);
- if (einv)
- exp *= -1.0f;
-
- f *= pow(10.0f, exp);
- }
-
- if (inv)
- f *= -1.0f;
-
- out = f;
- return c;
-}
-
-// ------------------------------------------------------------------------------------
-// The same but more human.
-inline float fast_atof(const char* c)
-{
- float ret;
- fast_atof_move(c, ret);
- return ret;
-}
-
-
-inline float fast_atof( const char* c, const char** cout)
-{
- float ret;
- *cout = fast_atof_move(c, ret);
-
- return ret;
-}
-
-inline float fast_atof( const char** inout)
-{
- float ret;
- *inout = fast_atof_move(*inout, ret);
-
- return ret;
-}
-
-} // end of namespace Assimp
-
-#endif
-
diff --git a/3rdparty/assimp/code/irrXMLWrapper.h b/3rdparty/assimp/code/irrXMLWrapper.h
deleted file mode 100644
index d3d0bbf7..00000000
--- a/3rdparty/assimp/code/irrXMLWrapper.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef INCLUDED_AI_IRRXML_WRAPPER
-#define INCLUDED_AI_IRRXML_WRAPPER
-
-// some long includes ....
-#include "./../contrib/irrXML/irrXML.h"
-#include "./../include/IOStream.h"
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-/** @brief Utility class to make IrrXML work together with our custom IO system
- * See the IrrXML docs for more details.
- *
- * Construct IrrXML-Reader in BaseImporter::InternReadFile():
- * @code
- * // open the file
- * boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
- * if ( file.get() == NULL) {
- * throw DeadlyImportError( "Failed to open file " + pFile + ".");
- * }
- *
- * // generate a XML reader for it
- * boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- * if ( !mReader) {
- * ThrowException( "xxxx: Unable to open file.");
- * }
- * @endcode
- **/
-class CIrrXML_IOStreamReader
- : public irr::io::IFileReadCallBack
-{
-public:
-
- // ----------------------------------------------------------------------------------
- //! Construction from an existing IOStream
- CIrrXML_IOStreamReader(IOStream* _stream)
- : stream (_stream)
- , t (0)
- {
-
- // Map the buffer into memory and convert it to UTF8. IrrXML provides its
- // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
- // it is not suitable for our purposes and we have to do it BEFORE IrrXML
- // gets the buffer. Sadly, this forces as to map the whole file into
- // memory.
-
- data.resize(stream->FileSize());
- stream->Read(&data[0],data.size(),1);
-
- BaseImporter::ConvertToUTF8(data);
- }
-
- // ----------------------------------------------------------------------------------
- //! Virtual destructor
- virtual ~CIrrXML_IOStreamReader() {};
-
- // ----------------------------------------------------------------------------------
- //! Reads an amount of bytes from the file.
- /** @param buffer: Pointer to output buffer.
- * @param sizeToRead: Amount of bytes to read
- * @return Returns how much bytes were read. */
- virtual int read(void* buffer, int sizeToRead) {
- if (sizeToRead<0) {
- return 0;
- }
- if (t+sizeToRead>data.size()) {
- sizeToRead = data.size()-t;
- }
-
- memcpy(buffer,&data.front()+t,sizeToRead);
-
- t += sizeToRead;
- return sizeToRead;
- }
-
- // ----------------------------------------------------------------------------------
- //! Returns size of file in bytes
- virtual int getSize() {
- return (int)data.size();
- }
-
-private:
- IOStream* stream;
- std::vector<char> data;
- size_t t;
-
-}; // ! class CIrrXML_IOStreamReader
-
-} // ! Assimp
-
-#endif // !! INCLUDED_AI_IRRXML_WRAPPER
diff --git a/3rdparty/assimp/code/makefile b/3rdparty/assimp/code/makefile
deleted file mode 100644
index 5710158d..00000000
--- a/3rdparty/assimp/code/makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-### USE OF THIS MAKEFILE IS NOT RECOMMENDED.
-### It is no longer maintained. Use CMAKE instead.
-
-# Makefile for Open Asset Import Library (GNU-make)
-# aramis_acg@users.sourceforge.net
-
-#
-# Usage: make <target> <macros>
-
-# TARGETS:
-# all Build a shared so from the whole library
-# clean Cleanup object files, prepare for rebuild
-# static Build a static library (*.a)
-# install SDK will be installed to /usr/bin/assimp
-
-# MACROS: (make clean before you change one)
-# NOBOOST=1 Build against boost workaround
-# SINGLETHREADED=1 Build single-threaded library
-# DEBUG=1 Build debug build of library
-
-# C++ object files
-OBJECTS := $(patsubst %.cpp,%.o, $(wildcard *.cpp))
-OBJECTS += $(patsubst %.cpp,%.o, $(wildcard extra/*.cpp))
-OBJECTS += $(patsubst %.cpp,%.o, $(wildcard ./../contrib/irrXML/*.cpp))
-
-# C object files
-OBJECTSC := $(patsubst %.c,%.oc, $(wildcard ./../contrib/zlib/*.c))
-OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/ConvertUTF/*.c))
-OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/unzip/*.c))
-
-# Directory for install
-INSTALLDIR = /usr/bin/assimp
-
-# Include flags for gcc
-INCLUDEFLAGS =
-
-# Preprocessor defines for gcc
-DEFINEFLAGS =
-
-# Suffix for the output binary, represents build type
-NAMESUFFIX =
-
-# Output path for binaries
-BINPATH = ../bin/gcc
-INCPATH = ../include
-
-# GCC compiler flags
-CPPFLAGS=-Wall
-
-# Setup environment for noboost build
-ifeq ($(NOBOOST),1)
- SINGLETHREADED = 1
- INCLUDEFLAGS += -IBoostWorkaround/
- DEFINEFLAGS += -DASSIMP_BUILD_BOOST_WORKAROUND
-# NAMESUFFIX += -noboost
-# else
-# INCLUDEFLAGS += -I"C:/Program Files/boost/boost_1_35_0"
-endif
-
-# Setup environment for st build
-ifeq ($(SINGLETHREADED),1)
- DEFINEFLAGS += -DASSIMP_BUILD_SINGLETHREADED
-# NAMESUFFIX += -st
-endif
-
-# Setup environment for debug build
-ifeq ($(DEBUG),1)
- DEFINEFLAGS += -D_DEBUG -DDEBUG
-# NAMESUFFIX += -debug
-else
- CPPFLAGS += -O3
- DEFINEFLAGS += -DNDEBUG -D_NDEBUG
-endif
-
-OUTPUT_NAME = dummy
-
-# Output name of shared library
-SHARED_TARGET = $(BINPATH)/libassimp$(NAMESUFFIX).so
-
-# Output name of static library
-STATIC = $(BINPATH)/libassimp$(NAMESUFFIX).a
-
-# target: all
-# usage : build a shared library (*.so)
-all: $(SHARED_TARGET)
-
-$(SHARED_TARGET): $(OBJECTS) $(OBJECTSC)
- gcc -o $@ $(OBJECTS) $(OBJECTSC) -shared -lstdc++
-%.o:%.cpp
- $(CXX) -g -c $(CPPFLAGS) $? -o $@ $(INCLUDEFLAGS) $(DEFINEFLAGS) -fPIC
-%.oc:%.c
- $(CXX) -x c -g -c -ansi $(CPPFLAGS) $? -o $@ -fPIC
-
-# target: clean
-# usage : cleanup all object files, prepare for a rebuild
-.PHONY: clean
-clean:
- -rm -f $(OBJECTS) $(OBJECTSC) $(TARGET)
-
-# target: static
-# usage : build a static library (*.a)
-static: $(STATIC)
-$(STATIC): $(OBJECTS) $(OBJECTSC)
- ar rcs $@ $(OBJECTS) $(OBJECTSC)
-
-install:
- mkdir -p $(INSTALLDIR)
- mkdir -p $(INSTALLDIR)/include
- mkdir -p $(INSTALLDIR)/lib
- cp $(BINPATH)/libassimp$(NAMESUFFIX).* $(INSTALLDIR)/lib
- cp $(INCPATH)/* $(INSTALLDIR)/include
diff --git a/3rdparty/assimp/code/makefile.mingw b/3rdparty/assimp/code/makefile.mingw
deleted file mode 100644
index c0b7bde0..00000000
--- a/3rdparty/assimp/code/makefile.mingw
+++ /dev/null
@@ -1,105 +0,0 @@
-### USE OF THIS MAKEFILE IS NOT RECOMMENDED.
-### It is no longer maintained. Use CMAKE instead.
-
-# ---------------------------------------------------------------------------
-# Makefile for Open Asset Import Library (MinGW32-make)
-# aramis_acg@users.sourceforge.net
-# - just a quick'n'dirty one, could be buggy ...
-#
-# Usage: mingw32-make -f makefile.mingw <target> <macros>
-
-# TARGETS:
-# all Build a shared so from the whole library
-# clean Cleanup object files, prepare for rebuild
-# static Build a static library (*.a)
-
-# MACROS: (make clean before you change one)
-# NOBOOST=1 Build against boost workaround
-# SINGLETHREADED=1 Build single-threaded library
-# DEBUG=1 Build debug build of library
-#
-# ---------------------------------------------------------------------------
-
-# C++ object files
-OBJECTS := $(patsubst %.cpp,%.o, $(wildcard *.cpp))
-OBJECTS += $(patsubst %.cpp,%.o, $(wildcard extra/*.cpp))
-OBJECTS += $(patsubst %.cpp,%.o, $(wildcard ./../contrib/irrXML/*.cpp))
-
-# C object files
-OBJECTSC := $(patsubst %.c,%.oc, $(wildcard ./../contrib/zlib/*.c))
-OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/ConvertUTF/*.c))
-OBJECTSC += $(patsubst %.c,%.oc, $(wildcard ./../contrib/unzip/*.c))
-
-# Include flags for gcc
-INCLUDEFLAGS =
-
-# Preprocessor defines for gcc
-DEFINEFLAGS =
-
-# Suffix for the output binary, represents build type
-NAMESUFFIX =
-
-# Output path for binaries
-BINPATH = ../bin/mingw/
-
-# GCC compiler flags
-CPPFLAGS=-Wall
-
-# Setup environment for noboost build
-ifeq ($(NOBOOST),1)
- SINGLETHREADED = 1
- INCLUDEFLAGS += -I./BoostWorkaround/
- DEFINEFLAGS += -DASSIMP_BUILD_BOOST_WORKAROUND
-# NAMESUFFIX += -noboost
-else
- # adjust this manually if your boost is stored elsewhere
- INCLUDEFLAGS += -I"C:/Program Files/boost/boost_1_38"
- #INCLUDEFLAGS += -I"$(BOOST_DIR)"
-
-endif
-
-# Setup environment for st build
-ifeq ($(SINGLETHREADED),1)
- DEFINEFLAGS += -DASSIMP_BUILD_SINGLETHREADED
-# NAMESUFFIX += -st
-endif
-
-# Setup environment for debug build
-ifeq ($(DEBUG),1)
- DEFINEFLAGS += -D_DEBUG -DDEBUG
- CPPFLAGS += -g
-# NAMESUFFIX += -debug
-else
- CPPFLAGS += -O2 -s
- DEFINEFLAGS += -DNDEBUG -D_NDEBUG
-endif
-
-# Output name of shared library
-SHARED_TARGET = $(BINPATH)/libassimp$(NAMESUFFIX).so
-
-# Output name of static library
-STATIC = $(BINPATH)/libassimp$(NAMESUFFIX).a
-
-# target: all
-# usage : build a shared library (*.so)
-all: $(SHARED_TARGET)
-
-$(SHARED_TARGET): $(OBJECTS) $(OBJECTSC)
- gcc -o $@ $(OBJECTS) $(OBJECTSC) -shared -lstdc++
-%.o:%.cpp
- $(CXX) -c $(CPPFLAGS) $? -o $@ $(INCLUDEFLAGS) $(DEFINEFLAGS)
-%.oc:%.c
- $(CXX) -x c -c -ansi $(CPPFLAGS) $? -o $@
-
-# target: clean
-# usage : cleanup all object files, prepare for a rebuild
-.PHONY: clean
-clean:
- -del *.o .\..\contrib\irrXML\*.o .\..\contrib\zlib\*.oc .\..\contrib\unzip\*.oc .\..\contrib\ConvertUTF\*.oc
-
-# target: static
-# usage : build a static library (*.a)
-static: $(STATIC)
-$(STATIC): $(OBJECTS) $(OBJECTSC)
- ar rcs $@ $(OBJECTS) $(OBJECTSC)
-
diff --git a/3rdparty/assimp/code/pstdint.h b/3rdparty/assimp/code/pstdint.h
deleted file mode 100644
index 0c1cec84..00000000
--- a/3rdparty/assimp/code/pstdint.h
+++ /dev/null
@@ -1,729 +0,0 @@
-/* A portable stdint.h
- ****************************************************************************
- * BSD License:
- ****************************************************************************
- *
- * Copyright (c) 2005-2007 Paul Hsieh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************
- *
- * Version 0.1.10
- *
- * The ANSI C standard committee, for the C99 standard, specified the
- * inclusion of a new standard include file called stdint.h. This is
- * a very useful and long desired include file which contains several
- * very precise definitions for integer scalar types that is
- * critically important for making portable several classes of
- * applications including cryptography, hashing, variable length
- * integer libraries and so on. But for most developers its likely
- * useful just for programming sanity.
- *
- * The problem is that most compiler vendors have decided not to
- * implement the C99 standard, and the next C++ language standard
- * (which has a lot more mindshare these days) will be a long time in
- * coming and its unknown whether or not it will include stdint.h or
- * how much adoption it will have. Either way, it will be a long time
- * before all compilers come with a stdint.h and it also does nothing
- * for the extremely large number of compilers available today which
- * do not include this file, or anything comparable to it.
- *
- * So that's what this file is all about. Its an attempt to build a
- * single universal include file that works on as many platforms as
- * possible to deliver what stdint.h is supposed to. A few things
- * that should be noted about this file:
- *
- * 1) It is not guaranteed to be portable and/or present an identical
- * interface on all platforms. The extreme variability of the
- * ANSI C standard makes this an impossibility right from the
- * very get go. Its really only meant to be useful for the vast
- * majority of platforms that possess the capability of
- * implementing usefully and precisely defined, standard sized
- * integer scalars. Systems which are not intrinsically 2s
- * complement may produce invalid constants.
- *
- * 2) There is an unavoidable use of non-reserved symbols.
- *
- * 3) Other standard include files are invoked.
- *
- * 4) This file may come in conflict with future platforms that do
- * include stdint.h. The hope is that one or the other can be
- * used with no real difference.
- *
- * 5) In the current verison, if your platform can't represent
- * int32_t, int16_t and int8_t, it just dumps out with a compiler
- * error.
- *
- * 6) 64 bit integers may or may not be defined. Test for their
- * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
- * Note that this is different from the C99 specification which
- * requires the existence of 64 bit support in the compiler. If
- * this is not defined for your platform, yet it is capable of
- * dealing with 64 bits then it is because this file has not yet
- * been extended to cover all of your system's capabilities.
- *
- * 7) (u)intptr_t may or may not be defined. Test for its presence
- * with the test: #ifdef PTRDIFF_MAX. If this is not defined
- * for your platform, then it is because this file has not yet
- * been extended to cover all of your system's capabilities, not
- * because its optional.
- *
- * 8) The following might not been defined even if your platform is
- * capable of defining it:
- *
- * WCHAR_MIN
- * WCHAR_MAX
- * (u)int64_t
- * PTRDIFF_MIN
- * PTRDIFF_MAX
- * (u)intptr_t
- *
- * 9) The following have not been defined:
- *
- * WINT_MIN
- * WINT_MAX
- *
- * 10) The criteria for defining (u)int_least(*)_t isn't clear,
- * except for systems which don't have a type that precisely
- * defined 8, 16, or 32 bit types (which this include file does
- * not support anyways). Default definitions have been given.
- *
- * 11) The criteria for defining (u)int_fast(*)_t isn't something I
- * would trust to any particular compiler vendor or the ANSI C
- * committee. It is well known that "compatible systems" are
- * commonly created that have very different performance
- * characteristics from the systems they are compatible with,
- * especially those whose vendors make both the compiler and the
- * system. Default definitions have been given, but its strongly
- * recommended that users never use these definitions for any
- * reason (they do *NOT* deliver any serious guarantee of
- * improved performance -- not in this file, nor any vendor's
- * stdint.h).
- *
- * 12) The following macros:
- *
- * PRINTF_INTMAX_MODIFIER
- * PRINTF_INT64_MODIFIER
- * PRINTF_INT32_MODIFIER
- * PRINTF_INT16_MODIFIER
- * PRINTF_LEAST64_MODIFIER
- * PRINTF_LEAST32_MODIFIER
- * PRINTF_LEAST16_MODIFIER
- * PRINTF_INTPTR_MODIFIER
- *
- * are strings which have been defined as the modifiers required
- * for the "d", "u" and "x" printf formats to correctly output
- * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
- * (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
- * PRINTF_INTPTR_MODIFIER is not defined for some systems which
- * provide their own stdint.h. PRINTF_INT64_MODIFIER is not
- * defined if INT64_MAX is not defined. These are an extension
- * beyond what C99 specifies must be in stdint.h.
- *
- * In addition, the following macros are defined:
- *
- * PRINTF_INTMAX_HEX_WIDTH
- * PRINTF_INT64_HEX_WIDTH
- * PRINTF_INT32_HEX_WIDTH
- * PRINTF_INT16_HEX_WIDTH
- * PRINTF_INT8_HEX_WIDTH
- * PRINTF_INTMAX_DEC_WIDTH
- * PRINTF_INT64_DEC_WIDTH
- * PRINTF_INT32_DEC_WIDTH
- * PRINTF_INT16_DEC_WIDTH
- * PRINTF_INT8_DEC_WIDTH
- *
- * Which specifies the maximum number of characters required to
- * print the number of that type in either hexadecimal or decimal.
- * These are an extension beyond what C99 specifies must be in
- * stdint.h.
- *
- * Compilers tested (all with 0 warnings at their highest respective
- * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
- * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
- * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
- *
- * This file should be considered a work in progress. Suggestions for
- * improvements, especially those which increase coverage are strongly
- * encouraged.
- *
- * Acknowledgements
- *
- * The following people have made significant contributions to the
- * development and testing of this file:
- *
- * Chris Howie
- * John Steele Scott
- * Dave Thorup
- *
- */
-
-#include <stddef.h>
-#include <limits.h>
-#include <signal.h>
-
-/*
- * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
- * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
- */
-
-#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) )) && !defined (_PSTDINT_H_INCLUDED)
-#include <stdint.h>
-#define _PSTDINT_H_INCLUDED
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-# endif
-# ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-# endif
-# ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-# endif
-# ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-# endif
-# ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "20"
-# endif
-# ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-# endif
-# ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-# endif
-# ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
-# endif
-
-/*
- * Something really weird is going on with Open Watcom. Just pull some of
- * these duplicated definitions from Open Watcom's stdint.h file for now.
- */
-
-# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
-# if !defined (INT64_C)
-# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
-# endif
-# if !defined (UINT64_C)
-# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
-# endif
-# if !defined (INT32_C)
-# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
-# endif
-# if !defined (UINT32_C)
-# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
-# endif
-# if !defined (INT16_C)
-# define INT16_C(x) (x)
-# endif
-# if !defined (UINT16_C)
-# define UINT16_C(x) (x)
-# endif
-# if !defined (INT8_C)
-# define INT8_C(x) (x)
-# endif
-# if !defined (UINT8_C)
-# define UINT8_C(x) (x)
-# endif
-# if !defined (UINT64_MAX)
-# define UINT64_MAX 18446744073709551615ULL
-# endif
-# if !defined (INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-# endif
-# if !defined (UINT32_MAX)
-# define UINT32_MAX 4294967295UL
-# endif
-# if !defined (INT32_MAX)
-# define INT32_MAX 2147483647L
-# endif
-# if !defined (INTMAX_MAX)
-# define INTMAX_MAX INT64_MAX
-# endif
-# if !defined (INTMAX_MIN)
-# define INTMAX_MIN INT64_MIN
-# endif
-# endif
-#endif
-
-#ifndef _PSTDINT_H_INCLUDED
-#define _PSTDINT_H_INCLUDED
-
-#ifndef SIZE_MAX
-# define SIZE_MAX (~(size_t)0)
-#endif
-
-/*
- * Deduce the type assignments from limits.h under the assumption that
- * integer sizes in bits are powers of 2, and follow the ANSI
- * definitions.
- */
-
-#ifndef UINT8_MAX
-# define UINT8_MAX 0xff
-#endif
-#ifndef uint8_t
-# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
- typedef unsigned char uint8_t;
-# define UINT8_C(v) ((uint8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef INT8_MAX
-# define INT8_MAX 0x7f
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN INT8_C(0x80)
-#endif
-#ifndef int8_t
-# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
- typedef signed char int8_t;
-# define INT8_C(v) ((int8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef UINT16_MAX
-# define UINT16_MAX 0xffff
-#endif
-#ifndef uint16_t
-#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
- typedef unsigned int uint16_t;
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-# define UINT16_C(v) ((uint16_t) (v))
-#elif (USHRT_MAX == UINT16_MAX)
- typedef unsigned short uint16_t;
-# define UINT16_C(v) ((uint16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT16_MAX
-# define INT16_MAX 0x7fff
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN INT16_C(0x8000)
-#endif
-#ifndef int16_t
-#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
- typedef signed int int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT16_MAX)
- typedef signed short int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef UINT32_MAX
-# define UINT32_MAX (0xffffffffUL)
-#endif
-#ifndef uint32_t
-#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
- typedef unsigned long uint32_t;
-# define UINT32_C(v) v ## UL
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (UINT_MAX == UINT32_MAX)
- typedef unsigned int uint32_t;
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-# define UINT32_C(v) v ## U
-#elif (USHRT_MAX == UINT32_MAX)
- typedef unsigned short uint32_t;
-# define UINT32_C(v) ((unsigned short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT32_MAX
-# define INT32_MAX (0x7fffffffL)
-#endif
-#ifndef INT32_MIN
-# define INT32_MIN INT32_C(0x80000000)
-#endif
-#ifndef int32_t
-#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
- typedef signed long int32_t;
-# define INT32_C(v) v ## L
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (INT_MAX == INT32_MAX)
- typedef signed int int32_t;
-# define INT32_C(v) v
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT32_MAX)
- typedef signed short int32_t;
-# define INT32_C(v) ((short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-/*
- * The macro stdint_int64_defined is temporarily used to record
- * whether or not 64 integer support is available. It must be
- * defined for any 64 integer extensions for new platforms that are
- * added.
- */
-
-#undef stdint_int64_defined
-#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
-# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# endif
-#endif
-
-#if !defined (stdint_int64_defined)
-# if defined(__GNUC__)
-# define stdint_int64_defined
- __extension__ typedef long long int64_t;
- __extension__ typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
-# define stdint_int64_defined
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
-# define UINT64_C(v) v ## UI64
-# define INT64_C(v) v ## I64
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "I64"
-# endif
-# endif
-#endif
-
-#if !defined (LONG_LONG_MAX) && defined (INT64_C)
-# define LONG_LONG_MAX INT64_C (9223372036854775807)
-#endif
-#ifndef ULONG_LONG_MAX
-# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
-#endif
-
-#if !defined (INT64_MAX) && defined (INT64_C)
-# define INT64_MAX INT64_C (9223372036854775807)
-#endif
-#if !defined (INT64_MIN) && defined (INT64_C)
-# define INT64_MIN INT64_C (-9223372036854775808)
-#endif
-#if !defined (UINT64_MAX) && defined (INT64_C)
-# define UINT64_MAX UINT64_C (18446744073709551615)
-#endif
-
-/*
- * Width of hexadecimal for number field.
- */
-
-#ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-#endif
-#ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-#endif
-#ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-#endif
-#ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-#endif
-
-#ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "20"
-#endif
-#ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-#endif
-#ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-#endif
-#ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-#endif
-
-/*
- * Ok, lets not worry about 128 bit integers for now. Moore's law says
- * we don't need to worry about that until about 2040 at which point
- * we'll have bigger things to worry about.
- */
-
-#ifdef stdint_int64_defined
- typedef int64_t intmax_t;
- typedef uint64_t uintmax_t;
-# define INTMAX_MAX INT64_MAX
-# define INTMAX_MIN INT64_MIN
-# define UINTMAX_MAX UINT64_MAX
-# define UINTMAX_C(v) UINT64_C(v)
-# define INTMAX_C(v) INT64_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
-# endif
-#else
- typedef int32_t intmax_t;
- typedef uint32_t uintmax_t;
-# define INTMAX_MAX INT32_MAX
-# define UINTMAX_MAX UINT32_MAX
-# define UINTMAX_C(v) UINT32_C(v)
-# define INTMAX_C(v) INT32_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
-# endif
-#endif
-
-/*
- * Because this file currently only supports platforms which have
- * precise powers of 2 as bit sizes for the default integers, the
- * least definitions are all trivial. Its possible that a future
- * version of this file could have different definitions.
- */
-
-#ifndef stdint_least_defined
- typedef int8_t int_least8_t;
- typedef uint8_t uint_least8_t;
- typedef int16_t int_least16_t;
- typedef uint16_t uint_least16_t;
- typedef int32_t int_least32_t;
- typedef uint32_t uint_least32_t;
-# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
-# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
-# define UINT_LEAST8_MAX UINT8_MAX
-# define INT_LEAST8_MAX INT8_MAX
-# define UINT_LEAST16_MAX UINT16_MAX
-# define INT_LEAST16_MAX INT16_MAX
-# define UINT_LEAST32_MAX UINT32_MAX
-# define INT_LEAST32_MAX INT32_MAX
-# define INT_LEAST8_MIN INT8_MIN
-# define INT_LEAST16_MIN INT16_MIN
-# define INT_LEAST32_MIN INT32_MIN
-# ifdef stdint_int64_defined
- typedef int64_t int_least64_t;
- typedef uint64_t uint_least64_t;
-# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
-# define UINT_LEAST64_MAX UINT64_MAX
-# define INT_LEAST64_MAX INT64_MAX
-# define INT_LEAST64_MIN INT64_MIN
-# endif
-#endif
-#undef stdint_least_defined
-
-/*
- * The ANSI C committee pretending to know or specify anything about
- * performance is the epitome of misguided arrogance. The mandate of
- * this file is to *ONLY* ever support that absolute minimum
- * definition of the fast integer types, for compatibility purposes.
- * No extensions, and no attempt to suggest what may or may not be a
- * faster integer type will ever be made in this file. Developers are
- * warned to stay away from these types when using this or any other
- * stdint.h.
- */
-
-typedef int_least8_t int_fast8_t;
-typedef uint_least8_t uint_fast8_t;
-typedef int_least16_t int_fast16_t;
-typedef uint_least16_t uint_fast16_t;
-typedef int_least32_t int_fast32_t;
-typedef uint_least32_t uint_fast32_t;
-#define UINT_FAST8_MAX UINT_LEAST8_MAX
-#define INT_FAST8_MAX INT_LEAST8_MAX
-#define UINT_FAST16_MAX UINT_LEAST16_MAX
-#define INT_FAST16_MAX INT_LEAST16_MAX
-#define UINT_FAST32_MAX UINT_LEAST32_MAX
-#define INT_FAST32_MAX INT_LEAST32_MAX
-#define INT_FAST8_MIN INT_LEAST8_MIN
-#define INT_FAST16_MIN INT_LEAST16_MIN
-#define INT_FAST32_MIN INT_LEAST32_MIN
-#ifdef stdint_int64_defined
- typedef int_least64_t int_fast64_t;
- typedef uint_least64_t uint_fast64_t;
-# define UINT_FAST64_MAX UINT_LEAST64_MAX
-# define INT_FAST64_MAX INT_LEAST64_MAX
-# define INT_FAST64_MIN INT_LEAST64_MIN
-#endif
-
-#undef stdint_int64_defined
-
-/*
- * Whatever piecemeal, per compiler thing we can do about the wchar_t
- * type limits.
- */
-
-#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
-# include <wchar.h>
-# ifndef WCHAR_MIN
-# define WCHAR_MIN 0
-# endif
-# ifndef WCHAR_MAX
-# define WCHAR_MAX ((wchar_t)-1)
-# endif
-#endif
-
-/*
- * Whatever piecemeal, per compiler/platform thing we can do about the
- * (u)intptr_t types and limits.
- */
-
-#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-#ifndef STDINT_H_UINTPTR_T_DEFINED
-# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
-# define stdint_intptr_bits 64
-# elif defined (__WATCOMC__) || defined (__TURBOC__)
-# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
-# define stdint_intptr_bits 16
-# else
-# define stdint_intptr_bits 32
-# endif
-# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
-# define stdint_intptr_bits 32
-# elif defined (__INTEL_COMPILER)
-/* TODO -- what will Intel do about x86-64? */
-# endif
-
-# ifdef stdint_intptr_bits
-# define stdint_intptr_glue3_i(a,b,c) a##b##c
-# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
-# ifndef PRINTF_INTPTR_MODIFIER
-# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
-# endif
-# ifndef PTRDIFF_MAX
-# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef PTRDIFF_MIN
-# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef UINTPTR_MAX
-# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MAX
-# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MIN
-# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef INTPTR_C
-# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
-# endif
-# ifndef UINTPTR_C
-# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
-# endif
- typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
- typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
-# else
-/* TODO -- This following is likely wrong for some platforms, and does
- nothing for the definition of uintptr_t. */
- typedef ptrdiff_t intptr_t;
-# endif
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-/*
- * Assumes sig_atomic_t is signed and we have a 2s complement machine.
- */
-
-#ifndef SIG_ATOMIC_MAX
-# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
-#endif
-
-#endif
-
diff --git a/3rdparty/assimp/code/qnan.h b/3rdparty/assimp/code/qnan.h
deleted file mode 100644
index c21dc86a..00000000
--- a/3rdparty/assimp/code/qnan.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development Team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the ASSIMP team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the ASSIMP Development Team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/** @file qnan.h
- * @brief Some utilities for our dealings with qnans.
- *
- * @note Some loaders use qnans to mark invalid values tempoarily, also
- * Assimp explicitly enforces undefined normals to be set to qnan.
- * qnan utilities are available in standard libraries (C99 for example)
- * but last time I checked compiler coverage was so bad that I decided
- * to reinvent the wheel.
- */
-
-#ifndef AI_QNAN_H_INCLUDED
-#define AI_QNAN_H_INCLUDED
-
-// ---------------------------------------------------------------------------
-/** Data structure to represent the bit pattern of a 32 Bit
- * IEEE 754 floating-point number. */
-union _IEEESingle
-{
- float Float;
- struct
- {
- uint32_t Frac : 23;
- uint32_t Exp : 8;
- uint32_t Sign : 1;
- } IEEE;
-} ;
-
-// ---------------------------------------------------------------------------
-/** Check whether a given float is qNaN.
- * @param in Input value */
-AI_FORCE_INLINE bool is_qnan(float in)
-{
- // the straightforward solution does not work:
- // return (in != in);
- // compiler generates code like this
- // load <in> to <register-with-different-width>
- // compare <register-with-different-width> against <in>
-
- // FIXME: Use <float> stuff instead? I think fpclassify needs C99
- return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1 &&
- reinterpret_cast<_IEEESingle*>(&in)->IEEE.Frac);
-}
-
-// ---------------------------------------------------------------------------
-/** Check whether a float is NOT qNaN.
- * @param in Input value */
-AI_FORCE_INLINE bool is_not_qnan(float in)
-{
- return !is_qnan(in);
-}
-
-// ---------------------------------------------------------------------------
-/** @brief check whether a float is either NaN or (+/-) INF.
- *
- * Denorms return false, they're treated like normal values.
- * @param in Input value */
-AI_FORCE_INLINE bool is_special_float(float in)
-{
- return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1);
-}
-
-// ---------------------------------------------------------------------------
-/** @brief Get a fresh qnan. */
-AI_FORCE_INLINE float get_qnan()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-#endif // !! AI_QNAN_H_INCLUDED
diff --git a/3rdparty/assimp/code/res/assimp.rc b/3rdparty/assimp/code/res/assimp.rc
deleted file mode 100644
index 5b3b5c06..00000000
--- a/3rdparty/assimp/code/res/assimp.rc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-#include "..\..\revision.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#define APSTUDIO_HIDDEN_SYMBOLS
-#include "windows.h"
-#undef APSTUDIO_HIDDEN_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// Deutsch (Deutschland) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
-#ifdef _WIN32
-LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
-#pragma code_page(1252)
-#endif //_WIN32
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,1,SVNRevision, 0
- PRODUCTVERSION 1,1,SVNRevision,0
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x7L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040704b0"
- BEGIN
- VALUE "Comments", "Licensed under a 3-clause BSD license"
- VALUE "CompanyName", "ASSIMP Development Team"
- VALUE "FileDescription", "Open Asset Import Library"
- VALUE "FileVersion", 1,1,SVNRevision,0
- VALUE "InternalName", "assimp "
- VALUE "LegalCopyright", "Copyright (C) 2006-2010"
- VALUE "OriginalFilename", "assimpNN.dll"
- VALUE "ProductName", "Open Asset Import Library"
- VALUE "ProductVersion", 1,1,SVNRevision,0
- ,0
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x407, 1200
- END
-END
-
-#endif // Deutsch (Deutschland) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/3rdparty/assimp/code/res/resource.h b/3rdparty/assimp/code/res/resource.h
deleted file mode 100644
index a2542fea..00000000
--- a/3rdparty/assimp/code/res/resource.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by assimp.rc
-
-// Nchste Standardwerte fr neue Objekte
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif