Refactor: Line endings are LF, not CRLF

pull/566/head
Richard 2015-05-18 21:48:29 -06:00
parent 8326535445
commit 4c1a0507fe
264 changed files with 112443 additions and 112445 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,282 +1,282 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file 3DSLoader.h /** @file 3DSLoader.h
* @brief 3DS File format loader * @brief 3DS File format loader
*/ */
#ifndef AI_3DSIMPORTER_H_INC #ifndef AI_3DSIMPORTER_H_INC
#define AI_3DSIMPORTER_H_INC #define AI_3DSIMPORTER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
#include "3DSHelper.h" #include "3DSHelper.h"
#include "StreamReader.h" #include "StreamReader.h"
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
using namespace D3DS; using namespace D3DS;
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files /** Importer class for 3D Studio r3 and r4 3DS files
*/ */
class Discreet3DSImporter : public BaseImporter class Discreet3DSImporter : public BaseImporter
{ {
public: public:
Discreet3DSImporter(); Discreet3DSImporter();
~Discreet3DSImporter(); ~Discreet3DSImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a temporary material to the outer representation /** Converts a temporary material to the outer representation
*/ */
void ConvertMaterial(D3DS::Material& p_cMat, void ConvertMaterial(D3DS::Material& p_cMat,
aiMaterial& p_pcOut); aiMaterial& p_pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read a chunk /** Read a chunk
* *
* @param pcOut Receives the current chunk * @param pcOut Receives the current chunk
*/ */
void ReadChunk(Discreet3DS::Chunk* pcOut); void ReadChunk(Discreet3DS::Chunk* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a percentage chunk. mCurrent will point to the next /** Parse a percentage chunk. mCurrent will point to the next
* chunk behind afterwards. If no percentage chunk is found * chunk behind afterwards. If no percentage chunk is found
* QNAN is returned. * QNAN is returned.
*/ */
float ParsePercentageChunk(); float ParsePercentageChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a color chunk. mCurrent will point to the next /** Parse a color chunk. mCurrent will point to the next
* chunk behind afterwards. If no color chunk is found * chunk behind afterwards. If no color chunk is found
* QNAN is returned in all members. * QNAN is returned in all members.
*/ */
void ParseColorChunk(aiColor3D* p_pcOut, void ParseColorChunk(aiColor3D* p_pcOut,
bool p_bAcceptPercent = true); bool p_bAcceptPercent = true);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Skip a chunk in the file /** Skip a chunk in the file
*/ */
void SkipChunk(); void SkipChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate the nodegraph /** Generate the nodegraph
*/ */
void GenerateNodeGraph(aiScene* pcOut); void GenerateNodeGraph(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a main top-level chunk in the file /** Parse a main top-level chunk in the file
*/ */
void ParseMainChunk(); void ParseMainChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level chunk in the file /** Parse a top-level chunk in the file
*/ */
void ParseChunk(const char* name, unsigned int num); void ParseChunk(const char* name, unsigned int num);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level editor chunk in the file /** Parse a top-level editor chunk in the file
*/ */
void ParseEditorChunk(); void ParseEditorChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level object chunk in the file /** Parse a top-level object chunk in the file
*/ */
void ParseObjectChunk(); void ParseObjectChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a material chunk in the file /** Parse a material chunk in the file
*/ */
void ParseMaterialChunk(); void ParseMaterialChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a mesh chunk in the file /** Parse a mesh chunk in the file
*/ */
void ParseMeshChunk(); void ParseMeshChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a light chunk in the file /** Parse a light chunk in the file
*/ */
void ParseLightChunk(); void ParseLightChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a camera chunk in the file /** Parse a camera chunk in the file
*/ */
void ParseCameraChunk(); void ParseCameraChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a face list chunk in the file /** Parse a face list chunk in the file
*/ */
void ParseFaceChunk(); void ParseFaceChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a keyframe chunk in the file /** Parse a keyframe chunk in the file
*/ */
void ParseKeyframeChunk(); void ParseKeyframeChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a hierarchy chunk in the file /** Parse a hierarchy chunk in the file
*/ */
void ParseHierarchyChunk(uint16_t parent); void ParseHierarchyChunk(uint16_t parent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a texture chunk in the file /** Parse a texture chunk in the file
*/ */
void ParseTextureChunk(D3DS::Texture* pcOut); void ParseTextureChunk(D3DS::Texture* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert the meshes in the file /** Convert the meshes in the file
*/ */
void ConvertMeshes(aiScene* pcOut); void ConvertMeshes(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Replace the default material in the scene /** Replace the default material in the scene
*/ */
void ReplaceDefaultMaterial(); void ReplaceDefaultMaterial();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert the whole scene /** Convert the whole scene
*/ */
void ConvertScene(aiScene* pcOut); void ConvertScene(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** generate unique vertices for a mesh /** generate unique vertices for a mesh
*/ */
void MakeUnique(D3DS::Mesh& sMesh); void MakeUnique(D3DS::Mesh& sMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Add a node to the node graph /** Add a node to the node graph
*/ */
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn, void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
aiMatrix4x4& absTrafo); aiMatrix4x4& absTrafo);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Search for a node in the graph. /** Search for a node in the graph.
* Called recursively * Called recursively
*/ */
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent); void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Apply the master scaling factor to the mesh /** Apply the master scaling factor to the mesh
*/ */
void ApplyMasterScale(aiScene* pScene); void ApplyMasterScale(aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Clamp all indices in the file to a valid range /** Clamp all indices in the file to a valid range
*/ */
void CheckIndices(D3DS::Mesh& sMesh); void CheckIndices(D3DS::Mesh& sMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Skip the TCB info in a track key /** Skip the TCB info in a track key
*/ */
void SkipTCBInfo(); void SkipTCBInfo();
protected: protected:
/** Stream to read from */ /** Stream to read from */
StreamReaderLE* stream; StreamReaderLE* stream;
/** Last touched node index */ /** Last touched node index */
short mLastNodeIndex; short mLastNodeIndex;
/** Current node, root node */ /** Current node, root node */
D3DS::Node* mCurrentNode, *mRootNode; D3DS::Node* mCurrentNode, *mRootNode;
/** Scene under construction */ /** Scene under construction */
D3DS::Scene* mScene; D3DS::Scene* mScene;
/** Ambient base color of the scene */ /** Ambient base color of the scene */
aiColor3D mClrAmbient; aiColor3D mClrAmbient;
/** Master scaling factor of the scene */ /** Master scaling factor of the scene */
float mMasterScale; float mMasterScale;
/** Path to the background image of the scene */ /** Path to the background image of the scene */
std::string mBackgroundImage; std::string mBackgroundImage;
bool bHasBG; bool bHasBG;
/** true if PRJ file */ /** true if PRJ file */
bool bIsPrj; bool bIsPrj;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,273 +1,273 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ACLoader.h /** @file ACLoader.h
* @brief Declaration of the .ac importer class. * @brief Declaration of the .ac importer class.
*/ */
#ifndef AI_AC3DLOADER_H_INCLUDED #ifndef AI_AC3DLOADER_H_INCLUDED
#define AI_AC3DLOADER_H_INCLUDED #define AI_AC3DLOADER_H_INCLUDED
#include <vector> #include <vector>
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
struct aiNode; struct aiNode;
struct aiMesh; struct aiMesh;
struct aiMaterial; struct aiMaterial;
struct aiLight; struct aiLight;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** AC3D (*.ac) importer class /** AC3D (*.ac) importer class
*/ */
class AC3DImporter : public BaseImporter class AC3DImporter : public BaseImporter
{ {
public: public:
AC3DImporter(); AC3DImporter();
~AC3DImporter(); ~AC3DImporter();
// Represents an AC3D material // Represents an AC3D material
struct Material struct Material
{ {
Material() Material()
: rgb (0.6f,0.6f,0.6f) : rgb (0.6f,0.6f,0.6f)
, spec (1.f,1.f,1.f) , spec (1.f,1.f,1.f)
, shin (0.f) , shin (0.f)
, trans (0.f) , trans (0.f)
{} {}
// base color of the material // base color of the material
aiColor3D rgb; aiColor3D rgb;
// ambient color of the material // ambient color of the material
aiColor3D amb; aiColor3D amb;
// emissive color of the material // emissive color of the material
aiColor3D emis; aiColor3D emis;
// specular color of the material // specular color of the material
aiColor3D spec; aiColor3D spec;
// shininess exponent // shininess exponent
float shin; float shin;
// transparency. 0 == opaque // transparency. 0 == opaque
float trans; float trans;
// name of the material. optional. // name of the material. optional.
std::string name; std::string name;
}; };
// Represents an AC3D surface // Represents an AC3D surface
struct Surface struct Surface
{ {
Surface() Surface()
: mat (0) : mat (0)
, flags (0) , flags (0)
{} {}
unsigned int mat,flags; unsigned int mat,flags;
typedef std::pair<unsigned int, aiVector2D > SurfaceEntry; typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
std::vector< SurfaceEntry > entries; std::vector< SurfaceEntry > entries;
}; };
// Represents an AC3D object // Represents an AC3D object
struct Object struct Object
{ {
Object() Object()
: type (World) : type (World)
, name( "" ) , name( "" )
, children() , children()
, texture( "" ) , texture( "" )
, texRepeat( 1.f, 1.f ) , texRepeat( 1.f, 1.f )
, texOffset( 0.0f, 0.0f ) , texOffset( 0.0f, 0.0f )
, rotation() , rotation()
, translation() , translation()
, vertices() , vertices()
, surfaces() , surfaces()
, numRefs (0) , numRefs (0)
, subDiv (0) , subDiv (0)
{} {}
// Type description // Type description
enum Type enum Type
{ {
World = 0x0, World = 0x0,
Poly = 0x1, Poly = 0x1,
Group = 0x2, Group = 0x2,
Light = 0x4 Light = 0x4
} type; } type;
// name of the object // name of the object
std::string name; std::string name;
// object children // object children
std::vector<Object> children; std::vector<Object> children;
// texture to be assigned to all surfaces of the object // texture to be assigned to all surfaces of the object
std::string texture; std::string texture;
// texture repat factors (scaling for all coordinates) // texture repat factors (scaling for all coordinates)
aiVector2D texRepeat, texOffset; aiVector2D texRepeat, texOffset;
// rotation matrix // rotation matrix
aiMatrix3x3 rotation; aiMatrix3x3 rotation;
// translation vector // translation vector
aiVector3D translation; aiVector3D translation;
// vertices // vertices
std::vector<aiVector3D> vertices; std::vector<aiVector3D> vertices;
// surfaces // surfaces
std::vector<Surface> surfaces; std::vector<Surface> surfaces;
// number of indices (= num verts in verbose format) // number of indices (= num verts in verbose format)
unsigned int numRefs; unsigned int numRefs;
// number of subdivisions to be performed on the // number of subdivisions to be performed on the
// imported data // imported data
unsigned int subDiv; unsigned int subDiv;
// max angle limit for smoothing // max angle limit for smoothing
float crease; float crease;
}; };
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details */ * See #BaseImporter::GetInfo for the details */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details*/ * See BaseImporter::InternReadFile() for details*/
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.*/ * basing on the Importer's configuration property list.*/
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get the next line from the file. /** Get the next line from the file.
* @return false if the end of the file was reached*/ * @return false if the end of the file was reached*/
bool GetNextLine(); bool GetNextLine();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Load the object section. This method is called recursively to /** Load the object section. This method is called recursively to
* load subobjects, the method returns after a 'kids 0' was * load subobjects, the method returns after a 'kids 0' was
* encountered. * encountered.
* @objects List of output objects*/ * @objects List of output objects*/
void LoadObjectSection(std::vector<Object>& objects); void LoadObjectSection(std::vector<Object>& objects);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert all objects into meshes and nodes. /** Convert all objects into meshes and nodes.
* @param object Current object to work on * @param object Current object to work on
* @param meshes Pointer to the list of output meshes * @param meshes Pointer to the list of output meshes
* @param outMaterials List of output materials * @param outMaterials List of output materials
* @param materials Material list * @param materials Material list
* @param Scenegraph node for the object */ * @param Scenegraph node for the object */
aiNode* ConvertObjectSection(Object& object, aiNode* ConvertObjectSection(Object& object,
std::vector<aiMesh*>& meshes, std::vector<aiMesh*>& meshes,
std::vector<aiMaterial*>& outMaterials, std::vector<aiMaterial*>& outMaterials,
const std::vector<Material>& materials, const std::vector<Material>& materials,
aiNode* parent = NULL); aiNode* parent = NULL);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert a material /** Convert a material
* @param object Current object * @param object Current object
* @param matSrc Source material description * @param matSrc Source material description
* @param matDest Destination material to be filled */ * @param matDest Destination material to be filled */
void ConvertMaterial(const Object& object, void ConvertMaterial(const Object& object,
const Material& matSrc, const Material& matSrc,
aiMaterial& matDest); aiMaterial& matDest);
private: private:
// points to the next data line // points to the next data line
const char* buffer; const char* buffer;
// Configuration option: if enabled, up to two meshes // Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have // are generated per material: those faces who have
// their bf cull flags set are separated. // their bf cull flags set are separated.
bool configSplitBFCull; bool configSplitBFCull;
// Configuration switch: subdivision surfaces are only // Configuration switch: subdivision surfaces are only
// evaluated if the value is true. // evaluated if the value is true.
bool configEvalSubdivision; bool configEvalSubdivision;
// counts how many objects we have in the tree. // counts how many objects we have in the tree.
// basing on this information we can find a // basing on this information we can find a
// good estimate how many meshes we'll have in the final scene. // good estimate how many meshes we'll have in the final scene.
unsigned int mNumMeshes; unsigned int mNumMeshes;
// current list of light sources // current list of light sources
std::vector<aiLight*>* mLights; std::vector<aiLight*>* mLights;
// name counters // name counters
unsigned int lights, groups, polys, worlds; unsigned int lights, groups, polys, worlds;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #endif // AI_AC3DIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,205 +1,205 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ASELoader.h /** @file ASELoader.h
* @brief Definition of the .ASE importer class. * @brief Definition of the .ASE importer class.
*/ */
#ifndef AI_ASELOADER_H_INCLUDED #ifndef AI_ASELOADER_H_INCLUDED
#define AI_ASELOADER_H_INCLUDED #define AI_ASELOADER_H_INCLUDED
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
struct aiNode; struct aiNode;
#include "ASEParser.h" #include "ASEParser.h"
namespace Assimp { namespace Assimp {
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** Importer class for the 3DS ASE ASCII format. /** Importer class for the 3DS ASE ASCII format.
* *
*/ */
class ASEImporter : public BaseImporter { class ASEImporter : public BaseImporter {
public: public:
ASEImporter(); ASEImporter();
~ASEImporter(); ~ASEImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate normal vectors basing on smoothing groups /** Generate normal vectors basing on smoothing groups
* (in some cases the normal are already contained in the file) * (in some cases the normal are already contained in the file)
* \param mesh Mesh to work on * \param mesh Mesh to work on
* \return false if the normals have been recomputed * \return false if the normals have been recomputed
*/ */
bool GenerateNormals(ASE::Mesh& mesh); bool GenerateNormals(ASE::Mesh& mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Create valid vertex/normal/UV/color/face lists. /** Create valid vertex/normal/UV/color/face lists.
* All elements are unique, faces have only one set of indices * All elements are unique, faces have only one set of indices
* after this step occurs. * after this step occurs.
* \param mesh Mesh to work on * \param mesh Mesh to work on
*/ */
void BuildUniqueRepresentation(ASE::Mesh& mesh); void BuildUniqueRepresentation(ASE::Mesh& mesh);
/** Create one-material-per-mesh meshes ;-) /** Create one-material-per-mesh meshes ;-)
* \param mesh Mesh to work with * \param mesh Mesh to work with
* \param Receives the list of all created meshes * \param Receives the list of all created meshes
*/ */
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut); void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert a material to a aiMaterial object /** Convert a material to a aiMaterial object
* \param mat Input material * \param mat Input material
*/ */
void ConvertMaterial(ASE::Material& mat); void ConvertMaterial(ASE::Material& mat);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Setup the final material indices for each mesh /** Setup the final material indices for each mesh
*/ */
void BuildMaterialIndices(); void BuildMaterialIndices();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build the node graph /** Build the node graph
*/ */
void BuildNodes(std::vector<ASE::BaseNode*>& nodes); void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build output cameras /** Build output cameras
*/ */
void BuildCameras(); void BuildCameras();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build output lights /** Build output lights
*/ */
void BuildLights(); void BuildLights();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build output animations /** Build output animations
*/ */
void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes); void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Add sub nodes to a node /** Add sub nodes to a node
* \param pcParent parent node to be filled * \param pcParent parent node to be filled
* \param szName Name of the parent node * \param szName Name of the parent node
* \param matrix Current transform * \param matrix Current transform
*/ */
void AddNodes(const std::vector<ASE::BaseNode*>& nodes, void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent,const char* szName); aiNode* pcParent,const char* szName);
void AddNodes(const std::vector<ASE::BaseNode*>& nodes, void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent,const char* szName, aiNode* pcParent,const char* szName,
const aiMatrix4x4& matrix); const aiMatrix4x4& matrix);
void AddMeshes(const ASE::BaseNode* snode,aiNode* node); void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate a default material and add it to the parser's list /** 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, * Called if no material has been found in the file (rare for ASE,
* but not impossible) * but not impossible)
*/ */
void GenerateDefaultMaterial(); void GenerateDefaultMaterial();
protected: protected:
/** Parser instance */ /** Parser instance */
ASE::Parser* mParser; ASE::Parser* mParser;
/** Buffer to hold the loaded file */ /** Buffer to hold the loaded file */
char* mBuffer; char* mBuffer;
/** Scene to be filled */ /** Scene to be filled */
aiScene* pcScene; aiScene* pcScene;
/** Config options: Recompute the normals in every case - WA /** Config options: Recompute the normals in every case - WA
for 3DS Max broken ASE normal export */ for 3DS Max broken ASE normal export */
bool configRecomputeNormals; bool configRecomputeNormals;
bool noSkeletonMesh; bool noSkeletonMesh;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,129 +1,129 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file AssimpCExport.cpp /** @file AssimpCExport.cpp
Assimp C export interface. See Exporter.cpp for some notes. Assimp C export interface. See Exporter.cpp for some notes.
*/ */
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#include "CInterfaceIOWrapper.h" #include "CInterfaceIOWrapper.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include "../include/assimp/Exporter.hpp" #include "../include/assimp/Exporter.hpp"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API size_t aiGetExportFormatCount(void) ASSIMP_API size_t aiGetExportFormatCount(void)
{ {
return Exporter().GetExportFormatCount(); return Exporter().GetExportFormatCount();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex) ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
{ {
// Note: this is valid as the index always pertains to a builtin exporter, // Note: this is valid as the index always pertains to a builtin exporter,
// for which the returned structure is guaranteed to be of static storage duration. // for which the returned structure is guaranteed to be of static storage duration.
return Exporter().GetExportFormatDescription(pIndex); return Exporter().GetExportFormatDescription(pIndex);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut) ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
{ {
if (!pOut || !pIn) { if (!pOut || !pIn) {
return; return;
} }
SceneCombiner::CopyScene(pOut,pIn,true); SceneCombiner::CopyScene(pOut,pIn,true);
ScenePriv(*pOut)->mIsCopy = true; ScenePriv(*pOut)->mIsCopy = true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn) ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
{ {
// note: aiReleaseImport() is also able to delete scene copies, but in addition // note: aiReleaseImport() is also able to delete scene copies, but in addition
// it also handles scenes with import metadata. // it also handles scenes with import metadata.
delete pIn; delete pIn;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing ) ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
{ {
return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing); return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing ) ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
{ {
Exporter exp; Exporter exp;
if (pIO) { if (pIO) {
exp.SetIOHandler(new CIOSystemWrapper(pIO)); exp.SetIOHandler(new CIOSystemWrapper(pIO));
} }
return exp.Export(pScene,pFormatId,pFileName,pPreprocessing); return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing ) ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
{ {
Exporter exp; Exporter exp;
if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) { if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
return NULL; return NULL;
} }
const aiExportDataBlob* blob = exp.GetOrphanedBlob(); const aiExportDataBlob* blob = exp.GetOrphanedBlob();
ai_assert(blob); ai_assert(blob);
return blob; return blob;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData ) ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
{ {
delete pData; delete pData;
} }
#endif // !ASSIMP_BUILD_NO_EXPORT #endif // !ASSIMP_BUILD_NO_EXPORT

File diff suppressed because it is too large Load Diff

View File

@ -1,131 +1,130 @@
/*
/* Open Asset Import Library (assimp)
Open Asset Import Library (assimp) ----------------------------------------------------------------------
----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team
Copyright (c) 2006-2015, assimp team All rights reserved.
All rights reserved.
Redistribution and use of this software in source and binary forms,
Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the
with or without modification, are permitted provided that the following conditions are met:
following conditions are met:
* Redistributions of source code must retain the above
* Redistributions of source code must retain the above copyright notice, this list of conditions and the
copyright notice, this list of conditions and the following disclaimer.
following disclaimer.
* Redistributions in binary form must reproduce the above
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
copyright notice, this list of conditions and the following disclaimer in the documentation and/or other
following disclaimer in the documentation and/or other materials provided with the distribution.
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
* Neither the name of the assimp team, nor the names of its contributors may be used to endorse or promote products
contributors may be used to endorse or promote products derived from this software without specific prior
derived from this software without specific prior written permission of the assimp team.
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
---------------------------------------------------------------------- */
*/
/** @file Definition of the .b3d importer class. */
/** @file Definition of the .b3d importer class. */
#ifndef AI_B3DIMPORTER_H_INC
#ifndef AI_B3DIMPORTER_H_INC #define AI_B3DIMPORTER_H_INC
#define AI_B3DIMPORTER_H_INC
#include "../include/assimp/types.h"
#include "../include/assimp/types.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/material.h"
#include "../include/assimp/material.h" #include "BaseImporter.h"
#include "BaseImporter.h"
#include <string>
#include <string> #include <vector>
#include <vector>
struct aiNodeAnim;
struct aiNodeAnim; struct aiNode;
struct aiNode; struct aiAnimation;
struct aiAnimation;
namespace Assimp{
namespace Assimp{
class B3DImporter : public BaseImporter{
class B3DImporter : public BaseImporter{ public:
public:
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
protected:
protected:
virtual const aiImporterDesc* GetInfo () const;
virtual const aiImporterDesc* GetInfo () const; virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
private:
private:
int ReadByte();
int ReadByte(); int ReadInt();
int ReadInt(); float ReadFloat();
float ReadFloat(); aiVector2D ReadVec2();
aiVector2D ReadVec2(); aiVector3D ReadVec3();
aiVector3D ReadVec3(); aiQuaternion ReadQuat();
aiQuaternion ReadQuat(); std::string ReadString();
std::string ReadString(); std::string ReadChunk();
std::string ReadChunk(); void ExitChunk();
void ExitChunk(); unsigned ChunkSize();
unsigned ChunkSize();
template<class T>
template<class T> T *to_array( const std::vector<T> &v );
T *to_array( const std::vector<T> &v );
struct Vertex{
struct Vertex{ aiVector3D vertex;
aiVector3D vertex; aiVector3D normal;
aiVector3D normal; aiVector3D texcoords;
aiVector3D texcoords; unsigned char bones[4];
unsigned char bones[4]; float weights[4];
float weights[4]; };
};
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
void ReadTEXS();
void ReadTEXS(); void ReadBRUS();
void ReadBRUS();
void ReadVRTS();
void ReadVRTS(); void ReadTRIS( int v0 );
void ReadTRIS( int v0 ); void ReadMESH();
void ReadMESH(); void ReadBONE( int id );
void ReadBONE( int id ); void ReadKEYS( aiNodeAnim *nodeAnim );
void ReadKEYS( aiNodeAnim *nodeAnim ); void ReadANIM();
void ReadANIM();
aiNode *ReadNODE( aiNode *parent );
aiNode *ReadNODE( aiNode *parent );
void ReadBB3D( aiScene *scene );
void ReadBB3D( aiScene *scene );
unsigned _pos;
unsigned _pos; // unsigned _size;
// unsigned _size; std::vector<unsigned char> _buf;
std::vector<unsigned char> _buf; std::vector<unsigned> _stack;
std::vector<unsigned> _stack;
std::vector<std::string> _textures;
std::vector<std::string> _textures; std::vector<aiMaterial*> _materials;
std::vector<aiMaterial*> _materials;
int _vflags,_tcsets,_tcsize;
int _vflags,_tcsets,_tcsize; std::vector<Vertex> _vertices;
std::vector<Vertex> _vertices;
std::vector<aiNode*> _nodes;
std::vector<aiNode*> _nodes; std::vector<aiMesh*> _meshes;
std::vector<aiMesh*> _meshes; std::vector<aiNodeAnim*> _nodeAnims;
std::vector<aiNodeAnim*> _nodeAnims; std::vector<aiAnimation*> _animations;
std::vector<aiAnimation*> _animations; };
};
}
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,171 +1,171 @@
/** Defines the BHV motion capturing loader class */ /** Defines the BHV motion capturing loader class */
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BVHLoader.h /** @file BVHLoader.h
* @brief Biovision BVH import * @brief Biovision BVH import
*/ */
#ifndef AI_BVHLOADER_H_INC #ifndef AI_BVHLOADER_H_INC
#define AI_BVHLOADER_H_INC #define AI_BVHLOADER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
struct aiNode; struct aiNode;
namespace Assimp namespace Assimp
{ {
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** Loader class to read Motion Capturing data from a .bvh file. /** 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 * 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 * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
* inside the loader just to be able to see something. * inside the loader just to be able to see something.
*/ */
class BVHLoader : public BaseImporter class BVHLoader : public BaseImporter
{ {
/** Possible animation channels for which the motion data holds the values */ /** Possible animation channels for which the motion data holds the values */
enum ChannelType enum ChannelType
{ {
Channel_PositionX, Channel_PositionX,
Channel_PositionY, Channel_PositionY,
Channel_PositionZ, Channel_PositionZ,
Channel_RotationX, Channel_RotationX,
Channel_RotationY, Channel_RotationY,
Channel_RotationZ Channel_RotationZ
}; };
/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */ /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
struct Node struct Node
{ {
const aiNode* mNode; const aiNode* mNode;
std::vector<ChannelType> mChannels; std::vector<ChannelType> mChannels;
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
Node() { } Node() { }
Node( const aiNode* pNode) : mNode( pNode) { } Node( const aiNode* pNode) : mNode( pNode) { }
}; };
public: public:
BVHLoader(); BVHLoader();
~BVHLoader(); ~BVHLoader();
public: public:
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
protected: protected:
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
protected: protected:
/** Reads the file */ /** Reads the file */
void ReadStructure( aiScene* pScene); void ReadStructure( aiScene* pScene);
/** Reads the hierarchy */ /** Reads the hierarchy */
void ReadHierarchy( aiScene* pScene); void ReadHierarchy( aiScene* pScene);
/** Reads a node and recursively its childs and returns the created node. */ /** Reads a node and recursively its childs and returns the created node. */
aiNode* ReadNode(); aiNode* ReadNode();
/** Reads an end node and returns the created node. */ /** Reads an end node and returns the created node. */
aiNode* ReadEndSite( const std::string& pParentName); aiNode* ReadEndSite( const std::string& pParentName);
/** Reads a node offset for the given node */ /** Reads a node offset for the given node */
void ReadNodeOffset( aiNode* pNode); void ReadNodeOffset( aiNode* pNode);
/** Reads the animation channels into the given node */ /** Reads the animation channels into the given node */
void ReadNodeChannels( BVHLoader::Node& pNode); void ReadNodeChannels( BVHLoader::Node& pNode);
/** Reads the motion data */ /** Reads the motion data */
void ReadMotion( aiScene* pScene); void ReadMotion( aiScene* pScene);
/** Retrieves the next token */ /** Retrieves the next token */
std::string GetNextToken(); std::string GetNextToken();
/** Reads the next token as a float */ /** Reads the next token as a float */
float GetNextTokenAsFloat(); float GetNextTokenAsFloat();
/** Aborts the file reading with an exception */ /** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
/** Constructs an animation for the motion data and stores it in the given scene */ /** Constructs an animation for the motion data and stores it in the given scene */
void CreateAnimation( aiScene* pScene); void CreateAnimation( aiScene* pScene);
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** Buffer to hold the loaded file */ /** Buffer to hold the loaded file */
std::vector<char> mBuffer; std::vector<char> mBuffer;
/** Next char to read from the buffer */ /** Next char to read from the buffer */
std::vector<char>::const_iterator mReader; std::vector<char>::const_iterator mReader;
/** Current line, for error messages */ /** Current line, for error messages */
unsigned int mLine; unsigned int mLine;
/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index. /** 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 * Also contain the motion data for the node's channels
*/ */
std::vector<Node> mNodes; std::vector<Node> mNodes;
/** basic Animation parameters */ /** basic Animation parameters */
float mAnimTickDuration; float mAnimTickDuration;
unsigned int mAnimNumFrames; unsigned int mAnimNumFrames;
bool noSkeletonMesh; bool noSkeletonMesh;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_BVHLOADER_H_INC #endif // AI_BVHLOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,375 +1,375 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Definition of the base class for all importer worker classes. */ /** @file Definition of the base class for all importer worker classes. */
#ifndef INCLUDED_AI_BASEIMPORTER_H #ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H #define INCLUDED_AI_BASEIMPORTER_H
#include "Exceptional.h" #include "Exceptional.h"
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <vector>
#include <set> #include <set>
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "../include/assimp/ProgressHandler.hpp" #include "../include/assimp/ProgressHandler.hpp"
struct aiScene; struct aiScene;
namespace Assimp { namespace Assimp {
class Importer; class Importer;
class IOSystem; class IOSystem;
class BaseProcess; class BaseProcess;
class SharedPostProcessInfo; class SharedPostProcessInfo;
class IOStream; class IOStream;
// utility to do char4 to uint32 in a portable manner // utility to do char4 to uint32 in a portable manner
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ #define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
(string[1] << 16) + (string[2] << 8) + string[3])) (string[1] << 16) + (string[2] << 8) + string[3]))
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> template <typename T>
struct ScopeGuard struct ScopeGuard
{ {
ScopeGuard(T* obj) : obj(obj), mdismiss() {} ScopeGuard(T* obj) : obj(obj), mdismiss() {}
~ScopeGuard () throw() { ~ScopeGuard () throw() {
if (!mdismiss) { if (!mdismiss) {
delete obj; delete obj;
} }
obj = NULL; obj = NULL;
} }
T* dismiss() { T* dismiss() {
mdismiss=true; mdismiss=true;
return obj; return obj;
} }
operator T*() { operator T*() {
return obj; return obj;
} }
T* operator -> () { T* operator -> () {
return obj; return obj;
} }
private: private:
// no copying allowed. // no copying allowed.
ScopeGuard(); ScopeGuard();
ScopeGuard( const ScopeGuard & ); ScopeGuard( const ScopeGuard & );
ScopeGuard &operator = ( const ScopeGuard & ); ScopeGuard &operator = ( const ScopeGuard & );
T* obj; T* obj;
bool mdismiss; bool mdismiss;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface /** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
* for all importer worker classes. * for all importer worker classes.
* *
* The interface defines two functions: CanRead() is used to check if the * 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 * importer can handle the format of the given file. If an implementation of
* this function returns true, the importer then calls ReadFile() which * this function returns true, the importer then calls ReadFile() which
* imports the given file. ReadFile is not overridable, it just calls * imports the given file. ReadFile is not overridable, it just calls
* InternReadFile() and catches any ImportErrorException that might occur. * InternReadFile() and catches any ImportErrorException that might occur.
*/ */
class ASSIMP_API BaseImporter class ASSIMP_API BaseImporter
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by #Importer */ /** Constructor to be privately used by #Importer */
BaseImporter(); BaseImporter();
/** Destructor, private as well */ /** Destructor, private as well */
virtual ~BaseImporter(); virtual ~BaseImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* *
* The implementation should be as quick as possible. A check for * The implementation should be as quick as possible. A check for
* the file extension is enough. If no suitable loader is found with * the file extension is enough. If no suitable loader is found with
* this strategy, CanRead() is called again, the 'checkSig' parameter * this strategy, CanRead() is called again, the 'checkSig' parameter
* set to true this time. Now the implementation is expected to * set to true this time. Now the implementation is expected to
* perform a full check of the file structure, possibly searching the * perform a full check of the file structure, possibly searching the
* first bytes of the file for magic identifiers or keywords. * first bytes of the file for magic identifiers or keywords.
* *
* @param pFile Path and file name of the file to be examined. * @param pFile Path and file name of the file to be examined.
* @param pIOHandler The IO handler to use for accessing any file. * @param pIOHandler The IO handler to use for accessing any file.
* @param checkSig Set to true if this method is called a second time. * @param checkSig Set to true if this method is called a second time.
* This time, the implementation may take more time to examine the * This time, the implementation may take more time to examine the
* contents of the file to be loaded for magic bytes, keywords, etc * contents of the file to be loaded for magic bytes, keywords, etc
* to be able to load files with unknown/not existent file extensions. * to be able to load files with unknown/not existent file extensions.
* @return true if the class can read this file, false if not. * @return true if the class can read this file, false if not.
*/ */
virtual bool CanRead( virtual bool CanRead(
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const = 0; ) const = 0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file and returns the imported data. /** Imports the given file and returns the imported data.
* If the import succeeds, ownership of the data is transferred to * If the import succeeds, ownership of the data is transferred to
* the caller. If the import fails, NULL is returned. The function * the caller. If the import fails, NULL is returned. The function
* takes care that any partially constructed data is destroyed * takes care that any partially constructed data is destroyed
* beforehand. * beforehand.
* *
* @param pImp #Importer object hosting this loader. * @param pImp #Importer object hosting this loader.
* @param pFile Path of the file to be imported. * @param pFile Path of the file to be imported.
* @param pIOHandler IO-Handler used to open this and possible other files. * @param pIOHandler IO-Handler used to open this and possible other files.
* @return The imported data or NULL if failed. If it failed a * @return The imported data or NULL if failed. If it failed a
* human-readable error description can be retrieved by calling * human-readable error description can be retrieved by calling
* GetErrorText() * GetErrorText()
* *
* @note This function is not intended to be overridden. Implement * @note This function is not intended to be overridden. Implement
* InternReadFile() to do the import. If an exception is thrown somewhere * InternReadFile() to do the import. If an exception is thrown somewhere
* in InternReadFile(), this function will catch it and transform it into * in InternReadFile(), this function will catch it and transform it into
* a suitable response to the caller. * a suitable response to the caller.
*/ */
aiScene* ReadFile( aiScene* ReadFile(
const Importer* pImp, const Importer* pImp,
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the error description of the last error that occured. /** Returns the error description of the last error that occured.
* @return A description of the last error that occured. An empty * @return A description of the last error that occured. An empty
* string if there was no error. * string if there was no error.
*/ */
const std::string& GetErrorText() const { const std::string& GetErrorText() const {
return mErrorText; return mErrorText;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
* @param pImp Importer instance * @param pImp Importer instance
*/ */
virtual void SetupProperties( virtual void SetupProperties(
const Importer* pImp const Importer* pImp
); );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called by #Importer::GetImporterInfo to get a description of /** Called by #Importer::GetImporterInfo to get a description of
* some loader features. Importers must provide this information. */ * some loader features. Importers must provide this information. */
virtual const aiImporterDesc* GetInfo() const = 0; virtual const aiImporterDesc* GetInfo() const = 0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer. /** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by * Take the extension list contained in the structure returned by
* #GetInfo and insert all file extensions into the given set. * #GetInfo and insert all file extensions into the given set.
* @param extension set to collect file extensions in*/ * @param extension set to collect file extensions in*/
void GetExtensionList(std::set<std::string>& extensions); void GetExtensionList(std::set<std::string>& extensions);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. The /** Imports the given file into the given scene structure. The
* function is expected to throw an ImportErrorException if there is * function is expected to throw an ImportErrorException if there is
* an error. If it terminates normally, the data in aiScene is * an error. If it terminates normally, the data in aiScene is
* expected to be correct. Override this function to implement the * expected to be correct. Override this function to implement the
* actual importing. * actual importing.
* <br> * <br>
* The output scene must meet the following requirements:<br> * The output scene must meet the following requirements:<br>
* <ul> * <ul>
* <li>At least a root node must be there, even if its only purpose * <li>At least a root node must be there, even if its only purpose
* is to reference one mesh.</li> * is to reference one mesh.</li>
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
* in the mesh are determined automatically in this case.</li> * in the mesh are determined automatically in this case.</li>
* <li>the vertex data is stored in a pseudo-indexed "verbose" format. * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
* In fact this means that every vertex that is referenced by * In fact this means that every vertex that is referenced by
* a face is unique. Or the other way round: a vertex index may * a face is unique. Or the other way round: a vertex index may
* not occur twice in a single aiMesh.</li> * not occur twice in a single aiMesh.</li>
* <li>aiAnimation::mDuration may be -1. Assimp determines the length * <li>aiAnimation::mDuration may be -1. Assimp determines the length
* of the animation automatically in this case as the length of * of the animation automatically in this case as the length of
* the longest animation channel.</li> * the longest animation channel.</li>
* <li>aiMesh::mBitangents may be NULL if tangents and normals are * <li>aiMesh::mBitangents may be NULL if tangents and normals are
* given. In this case bitangents are computed as the cross product * given. In this case bitangents are computed as the cross product
* between normal and tangent.</li> * between normal and tangent.</li>
* <li>There needn't be a material. If none is there a default material * <li>There needn't be a material. If none is there a default material
* is generated. However, it is recommended practice for loaders * is generated. However, it is recommended practice for loaders
* to generate a default material for yourself that matches the * to generate a default material for yourself that matches the
* default material setting for the file format better than Assimp's * default material setting for the file format better than Assimp's
* generic default material. Note that default materials *should* * generic default material. Note that default materials *should*
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
* texture. </li> * texture. </li>
* </ul> * </ul>
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul> * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
* <li> at least one mesh must be there</li> * <li> at least one mesh must be there</li>
* <li> there may be no meshes with 0 vertices or faces</li> * <li> there may be no meshes with 0 vertices or faces</li>
* </ul> * </ul>
* This won't be checked (except by the validation step): Assimp will * This won't be checked (except by the validation step): Assimp will
* crash if one of the conditions is not met! * crash if one of the conditions is not met!
* *
* @param pFile Path of the file to be imported. * @param pFile Path of the file to be imported.
* @param pScene The scene object to hold the imported data. * @param pScene The scene object to hold the imported data.
* NULL is not a valid parameter. * NULL is not a valid parameter.
* @param pIOHandler The IO handler to use for any file access. * @param pIOHandler The IO handler to use for any file access.
* NULL is not a valid parameter. */ * NULL is not a valid parameter. */
virtual void InternReadFile( virtual void InternReadFile(
const std::string& pFile, const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
) = 0; ) = 0;
public: // static utilities public: // static utilities
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** A utility for CanRead(). /** A utility for CanRead().
* *
* The function searches the header of a file for a specific token * The function searches the header of a file for a specific token
* and returns true if this token is found. This works for text * and returns true if this token is found. This works for text
* files only. There is a rudimentary handling of UNICODE files. * files only. There is a rudimentary handling of UNICODE files.
* The comparison is case independent. * The comparison is case independent.
* *
* @param pIOSystem IO System to work with * @param pIOSystem IO System to work with
* @param file File name of the file * @param file File name of the file
* @param tokens List of tokens to search for * @param tokens List of tokens to search for
* @param numTokens Size of the token array * @param numTokens Size of the token array
* @param searchBytes Number of bytes to be searched for the tokens. * @param searchBytes Number of bytes to be searched for the tokens.
*/ */
static bool SearchFileHeaderForToken( static bool SearchFileHeaderForToken(
IOSystem* pIOSystem, IOSystem* pIOSystem,
const std::string& file, const std::string& file,
const char** tokens, const char** tokens,
unsigned int numTokens, unsigned int numTokens,
unsigned int searchBytes = 200, unsigned int searchBytes = 200,
bool tokensSol = false); bool tokensSol = false);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Check whether a file has a specific file extension /** @brief Check whether a file has a specific file extension
* @param pFile Input file * @param pFile Input file
* @param ext0 Extension to check for. Lowercase characters only, no dot! * @param ext0 Extension to check for. Lowercase characters only, no dot!
* @param ext1 Optional second extension * @param ext1 Optional second extension
* @param ext2 Optional third extension * @param ext2 Optional third extension
* @note Case-insensitive * @note Case-insensitive
*/ */
static bool SimpleExtensionCheck ( static bool SimpleExtensionCheck (
const std::string& pFile, const std::string& pFile,
const char* ext0, const char* ext0,
const char* ext1 = NULL, const char* ext1 = NULL,
const char* ext2 = NULL); const char* ext2 = NULL);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Extract file extension from a string /** @brief Extract file extension from a string
* @param pFile Input file * @param pFile Input file
* @return Extension without trailing dot, all lowercase * @return Extension without trailing dot, all lowercase
*/ */
static std::string GetExtension ( static std::string GetExtension (
const std::string& pFile); const std::string& pFile);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Check whether a file starts with one or more magic tokens /** @brief Check whether a file starts with one or more magic tokens
* @param pFile Input file * @param pFile Input file
* @param pIOHandler IO system to be used * @param pIOHandler IO system to be used
* @param magic n magic tokens * @param magic n magic tokens
* @params num Size of magic * @params num Size of magic
* @param offset Offset from file start where tokens are located * @param offset Offset from file start where tokens are located
* @param Size of one token, in bytes. Maximally 16 bytes. * @param Size of one token, in bytes. Maximally 16 bytes.
* @return true if one of the given tokens was found * @return true if one of the given tokens was found
* *
* @note For convinence, the check is also performed for the * @note For convinence, the check is also performed for the
* byte-swapped variant of all tokens (big endian). Only for * byte-swapped variant of all tokens (big endian). Only for
* tokens of size 2,4. * tokens of size 2,4.
*/ */
static bool CheckMagicToken( static bool CheckMagicToken(
IOSystem* pIOHandler, IOSystem* pIOHandler,
const std::string& pFile, const std::string& pFile,
const void* magic, const void* magic,
unsigned int num, unsigned int num,
unsigned int offset = 0, unsigned int offset = 0,
unsigned int size = 4); unsigned int size = 4);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** An utility for all text file loaders. It converts a file to our /** An utility for all text file loaders. It converts a file to our
* UTF8 character set. Errors are reported, but ignored. * UTF8 character set. Errors are reported, but ignored.
* *
* @param data File buffer to be converted to UTF8 data. The buffer * @param data File buffer to be converted to UTF8 data. The buffer
* is resized as appropriate. */ * is resized as appropriate. */
static void ConvertToUTF8( static void ConvertToUTF8(
std::vector<char>& data); std::vector<char>& data);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** An utility for all text file loaders. It converts a file from our /** An utility for all text file loaders. It converts a file from our
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
* *
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
* is resized as appropriate. */ * is resized as appropriate. */
static void ConvertUTF8toISO8859_1( static void ConvertUTF8toISO8859_1(
std::string& data); std::string& data);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Utility for text file loaders which copies the contents of the /** Utility for text file loaders which copies the contents of the
* file into a memory buffer and converts it to our UTF8 * file into a memory buffer and converts it to our UTF8
* representation. * representation.
* @param stream Stream to read from. * @param stream Stream to read from.
* @param data Output buffer to be resized and filled with the * @param data Output buffer to be resized and filled with the
* converted text file data. The buffer is terminated with * converted text file data. The buffer is terminated with
* a binary 0. */ * a binary 0. */
static void TextFileToBuffer( static void TextFileToBuffer(
IOStream* stream, IOStream* stream,
std::vector<char>& data); std::vector<char>& data);
protected: protected:
/** Error description in case there was one. */ /** Error description in case there was one. */
std::string mErrorText; std::string mErrorText;
/** Currently set progress handler */ /** Currently set progress handler */
ProgressHandler* progress; ProgressHandler* progress;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_BASEIMPORTER_H_INC #endif // AI_BASEIMPORTER_H_INC

View File

@ -1,105 +1,105 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of BaseProcess */ /** @file Implementation of BaseProcess */
#include "BaseImporter.h" #include "BaseImporter.h"
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include "Importer.h" #include "Importer.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseProcess::BaseProcess() BaseProcess::BaseProcess()
: shared() : shared()
, progress() , progress()
{ {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
BaseProcess::~BaseProcess() BaseProcess::~BaseProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BaseProcess::ExecuteOnScene( Importer* pImp) void BaseProcess::ExecuteOnScene( Importer* pImp)
{ {
ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene); ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene);
progress = pImp->GetProgressHandler(); progress = pImp->GetProgressHandler();
ai_assert(progress); ai_assert(progress);
SetupProperties( pImp ); SetupProperties( pImp );
// catch exceptions thrown inside the PostProcess-Step // catch exceptions thrown inside the PostProcess-Step
try try
{ {
Execute(pImp->Pimpl()->mScene); Execute(pImp->Pimpl()->mScene);
} catch( const std::exception& err ) { } catch( const std::exception& err ) {
// extract error description // extract error description
pImp->Pimpl()->mErrorString = err.what(); pImp->Pimpl()->mErrorString = err.what();
DefaultLogger::get()->error(pImp->Pimpl()->mErrorString); DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
// and kill the partially imported data // and kill the partially imported data
delete pImp->Pimpl()->mScene; delete pImp->Pimpl()->mScene;
pImp->Pimpl()->mScene = NULL; pImp->Pimpl()->mScene = NULL;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BaseProcess::SetupProperties(const Importer* /*pImp*/) void BaseProcess::SetupProperties(const Importer* /*pImp*/)
{ {
// the default implementation does nothing // the default implementation does nothing
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BaseProcess::RequireVerboseFormat() const bool BaseProcess::RequireVerboseFormat() const
{ {
return true; return true;
} }

View File

@ -1,294 +1,294 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Base class of all import post processing steps */ /** @file Base class of all import post processing steps */
#ifndef INCLUDED_AI_BASEPROCESS_H #ifndef INCLUDED_AI_BASEPROCESS_H
#define INCLUDED_AI_BASEPROCESS_H #define INCLUDED_AI_BASEPROCESS_H
#include <map> #include <map>
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "GenericProperty.h" #include "GenericProperty.h"
struct aiScene; struct aiScene;
namespace Assimp { namespace Assimp {
class Importer; class Importer;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper class to allow post-processing steps to interact with each other. /** 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 * The class maintains a simple property list that can be used by pp-steps
* to provide additional information to other steps. This is primarily * to provide additional information to other steps. This is primarily
* intended for cross-step optimizations. * intended for cross-step optimizations.
*/ */
class SharedPostProcessInfo class SharedPostProcessInfo
{ {
public: public:
struct Base struct Base
{ {
virtual ~Base() virtual ~Base()
{} {}
}; };
//! Represents data that is allocated on the heap, thus needs to be deleted //! Represents data that is allocated on the heap, thus needs to be deleted
template <typename T> template <typename T>
struct THeapData : public Base struct THeapData : public Base
{ {
THeapData(T* in) THeapData(T* in)
: data (in) : data (in)
{} {}
~THeapData() ~THeapData()
{ {
delete data; delete data;
} }
T* data; T* data;
}; };
//! Represents static, by-value data not allocated on the heap //! Represents static, by-value data not allocated on the heap
template <typename T> template <typename T>
struct TStaticData : public Base struct TStaticData : public Base
{ {
TStaticData(T in) TStaticData(T in)
: data (in) : data (in)
{} {}
~TStaticData() ~TStaticData()
{} {}
T data; T data;
}; };
// some typedefs for cleaner code // some typedefs for cleaner code
typedef unsigned int KeyType; typedef unsigned int KeyType;
typedef std::map<KeyType, Base*> PropertyMap; typedef std::map<KeyType, Base*> PropertyMap;
public: public:
//! Destructor //! Destructor
~SharedPostProcessInfo() ~SharedPostProcessInfo()
{ {
Clean(); Clean();
} }
//! Remove all stored properties from the table //! Remove all stored properties from the table
void Clean() void Clean()
{ {
// invoke the virtual destructor for all stored properties // invoke the virtual destructor for all stored properties
for (PropertyMap::iterator it = pmap.begin(), end = pmap.end(); for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
it != end; ++it) it != end; ++it)
{ {
delete (*it).second; delete (*it).second;
} }
pmap.clear(); pmap.clear();
} }
//! Add a heap property to the list //! Add a heap property to the list
template <typename T> template <typename T>
void AddProperty( const char* name, T* in ){ void AddProperty( const char* name, T* in ){
AddProperty(name,(Base*)new THeapData<T>(in)); AddProperty(name,(Base*)new THeapData<T>(in));
} }
//! Add a static by-value property to the list //! Add a static by-value property to the list
template <typename T> template <typename T>
void AddProperty( const char* name, T in ){ void AddProperty( const char* name, T in ){
AddProperty(name,(Base*)new TStaticData<T>(in)); AddProperty(name,(Base*)new TStaticData<T>(in));
} }
//! Get a heap property //! Get a heap property
template <typename T> template <typename T>
bool GetProperty( const char* name, T*& out ) const bool GetProperty( const char* name, T*& out ) const
{ {
THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name); THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
if(!t) if(!t)
{ {
out = NULL; out = NULL;
return false; return false;
} }
out = t->data; out = t->data;
return true; return true;
} }
//! Get a static, by-value property //! Get a static, by-value property
template <typename T> template <typename T>
bool GetProperty( const char* name, T& out ) const bool GetProperty( const char* name, T& out ) const
{ {
TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name); TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
if(!t)return false; if(!t)return false;
out = t->data; out = t->data;
return true; return true;
} }
//! Remove a property of a specific type //! Remove a property of a specific type
void RemoveProperty( const char* name) { void RemoveProperty( const char* name) {
SetGenericPropertyPtr<Base>(pmap,name,NULL); SetGenericPropertyPtr<Base>(pmap,name,NULL);
} }
private: private:
void AddProperty( const char* name, Base* data) { void AddProperty( const char* name, Base* data) {
SetGenericPropertyPtr<Base>(pmap,name,data); SetGenericPropertyPtr<Base>(pmap,name,data);
} }
Base* GetPropertyInternal( const char* name) const { Base* GetPropertyInternal( const char* name) const {
return GetGenericProperty<Base*>(pmap,name,NULL); return GetGenericProperty<Base*>(pmap,name,NULL);
} }
private: private:
//! Map of all stored properties //! Map of all stored properties
PropertyMap pmap; PropertyMap pmap;
}; };
#if 0 #if 0
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Represents a dependency table for a postprocessing steps. /** @brief Represents a dependency table for a postprocessing steps.
* *
* For future use. * For future use.
*/ */
struct PPDependencyTable struct PPDependencyTable
{ {
unsigned int execute_me_before_these; unsigned int execute_me_before_these;
unsigned int execute_me_after_these; unsigned int execute_me_after_these;
unsigned int only_if_these_are_not_specified; unsigned int only_if_these_are_not_specified;
unsigned int mutually_exclusive_with; unsigned int mutually_exclusive_with;
}; };
#endif #endif
#define AI_SPP_SPATIAL_SORT "$Spat" #define AI_SPP_SPATIAL_SORT "$Spat"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The BaseProcess defines a common interface for all post processing steps. /** The BaseProcess defines a common interface for all post processing steps.
* A post processing step is run after a successful import if the caller * A post processing step is run after a successful import if the caller
* specified the corresponding flag when calling ReadFile(). * specified the corresponding flag when calling ReadFile().
* Enum #aiPostProcessSteps defines which flags are available. * Enum #aiPostProcessSteps defines which flags are available.
* After a successful import the Importer iterates over its internal array * After a successful import the Importer iterates over its internal array
* of processes and calls IsActive() on each process to evaluate if the step * of processes and calls IsActive() on each process to evaluate if the step
* should be executed. If the function returns true, the class' Execute() * should be executed. If the function returns true, the class' Execute()
* function is called subsequently. * function is called subsequently.
*/ */
class ASSIMP_API_WINONLY BaseProcess class ASSIMP_API_WINONLY BaseProcess
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
BaseProcess(); BaseProcess();
/** Destructor, private as well */ /** Destructor, private as well */
virtual ~BaseProcess(); virtual ~BaseProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. A * @param pFlags The processing flags the importer was called with. A
* bitwise combination of #aiPostProcessSteps. * bitwise combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, * @return true if the process is present in this flag fields,
* false if not. * false if not.
*/ */
virtual bool IsActive( unsigned int pFlags) const = 0; virtual bool IsActive( unsigned int pFlags) const = 0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Check whether this step expects its input vertex data to be /** Check whether this step expects its input vertex data to be
* in verbose format. */ * in verbose format. */
virtual bool RequireVerboseFormat() const; virtual bool RequireVerboseFormat() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* The function deletes the scene if the postprocess step fails ( * The function deletes the scene if the postprocess step fails (
* the object pointer will be set to NULL). * the object pointer will be set to NULL).
* @param pImp Importer instance (pImp->mScene must be valid) * @param pImp Importer instance (pImp->mScene must be valid)
*/ */
void ExecuteOnScene( Importer* pImp); void ExecuteOnScene( Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ExecuteOnScene(). /** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration * The function is a request to the process to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
virtual void SetupProperties(const Importer* pImp); virtual void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* A process should throw an ImportErrorException* if it fails. * A process should throw an ImportErrorException* if it fails.
* This method must be implemented by deriving classes. * This method must be implemented by deriving classes.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
virtual void Execute( aiScene* pScene) = 0; virtual void Execute( aiScene* pScene) = 0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Assign a new SharedPostProcessInfo to the step. This object /** Assign a new SharedPostProcessInfo to the step. This object
* allows multiple postprocess steps to share data. * allows multiple postprocess steps to share data.
* @param sh May be NULL * @param sh May be NULL
*/ */
inline void SetSharedData(SharedPostProcessInfo* sh) { inline void SetSharedData(SharedPostProcessInfo* sh) {
shared = sh; shared = sh;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get the shared data that is assigned to the step. /** Get the shared data that is assigned to the step.
*/ */
inline SharedPostProcessInfo* GetSharedData() { inline SharedPostProcessInfo* GetSharedData() {
return shared; return shared;
} }
protected: protected:
/** See the doc of #SharedPostProcessInfo for more details */ /** See the doc of #SharedPostProcessInfo for more details */
SharedPostProcessInfo* shared; SharedPostProcessInfo* shared;
/** Currently active progress handler */ /** Currently active progress handler */
ProgressHandler* progress; ProgressHandler* progress;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_BASEPROCESS_H_INC #endif // AI_BASEPROCESS_H_INC

View File

@ -1,373 +1,373 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderDNA.cpp /** @file BlenderDNA.cpp
* @brief Implementation of the Blender `DNA`, that is its own * @brief Implementation of the Blender `DNA`, that is its own
* serialized set of data structures. * serialized set of data structures.
*/ */
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "StreamReader.h" #include "StreamReader.h"
#include "fast_atof.h" #include "fast_atof.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
#define for_each BOOST_FOREACH #define for_each BOOST_FOREACH
bool match4(StreamReaderAny& stream, const char* string) { bool match4(StreamReaderAny& stream, const char* string) {
char tmp[] = { char tmp[] = {
(stream).GetI1(), (stream).GetI1(),
(stream).GetI1(), (stream).GetI1(),
(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]); return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
} }
struct Type { struct Type {
size_t size; size_t size;
std::string name; std::string name;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNAParser :: Parse () void DNAParser :: Parse ()
{ {
StreamReaderAny& stream = *db.reader.get(); StreamReaderAny& stream = *db.reader.get();
DNA& dna = db.dna; DNA& dna = db.dna;
if(!match4(stream,"SDNA")) { if(!match4(stream,"SDNA")) {
throw DeadlyImportError("BlenderDNA: Expected SDNA chunk"); throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
} }
// name dictionary // name dictionary
if(!match4(stream,"NAME")) { if(!match4(stream,"NAME")) {
throw DeadlyImportError("BlenderDNA: Expected NAME field"); throw DeadlyImportError("BlenderDNA: Expected NAME field");
} }
std::vector<std::string> names (stream.GetI4()); std::vector<std::string> names (stream.GetI4());
for_each(std::string& s, names) { for_each(std::string& s, names) {
while (char c = stream.GetI1()) { while (char c = stream.GetI1()) {
s += c; s += c;
} }
} }
// type dictionary // type dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"TYPE")) { if(!match4(stream,"TYPE")) {
throw DeadlyImportError("BlenderDNA: Expected TYPE field"); throw DeadlyImportError("BlenderDNA: Expected TYPE field");
} }
std::vector<Type> types (stream.GetI4()); std::vector<Type> types (stream.GetI4());
for_each(Type& s, types) { for_each(Type& s, types) {
while (char c = stream.GetI1()) { while (char c = stream.GetI1()) {
s.name += c; s.name += c;
} }
} }
// type length dictionary // type length dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"TLEN")) { if(!match4(stream,"TLEN")) {
throw DeadlyImportError("BlenderDNA: Expected TLEN field"); throw DeadlyImportError("BlenderDNA: Expected TLEN field");
} }
for_each(Type& s, types) { for_each(Type& s, types) {
s.size = stream.GetI2(); s.size = stream.GetI2();
} }
// structures dictionary // structures dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"STRC")) { if(!match4(stream,"STRC")) {
throw DeadlyImportError("BlenderDNA: Expected STRC field"); throw DeadlyImportError("BlenderDNA: Expected STRC field");
} }
size_t end = stream.GetI4(), fields = 0; size_t end = stream.GetI4(), fields = 0;
dna.structures.reserve(end); dna.structures.reserve(end);
for(size_t i = 0; i != end; ++i) { for(size_t i = 0; i != end; ++i) {
uint16_t n = stream.GetI2(); uint16_t n = stream.GetI2();
if (n >= types.size()) { if (n >= types.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure name" ,n, "BlenderDNA: Invalid type index in structure name" ,n,
" (there are only ", types.size(), " entries)" " (there are only ", types.size(), " entries)"
)); ));
} }
// maintain separate indexes // maintain separate indexes
dna.indices[types[n].name] = dna.structures.size(); dna.indices[types[n].name] = dna.structures.size();
dna.structures.push_back(Structure()); dna.structures.push_back(Structure());
Structure& s = dna.structures.back(); Structure& s = dna.structures.back();
s.name = types[n].name; s.name = types[n].name;
//s.index = dna.structures.size()-1; //s.index = dna.structures.size()-1;
n = stream.GetI2(); n = stream.GetI2();
s.fields.reserve(n); s.fields.reserve(n);
size_t offset = 0; size_t offset = 0;
for (size_t m = 0; m < n; ++m, ++fields) { for (size_t m = 0; m < n; ++m, ++fields) {
uint16_t j = stream.GetI2(); uint16_t j = stream.GetI2();
if (j >= types.size()) { if (j >= types.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure field ", j, "BlenderDNA: Invalid type index in structure field ", j,
" (there are only ", types.size(), " entries)" " (there are only ", types.size(), " entries)"
)); ));
} }
s.fields.push_back(Field()); s.fields.push_back(Field());
Field& f = s.fields.back(); Field& f = s.fields.back();
f.offset = offset; f.offset = offset;
f.type = types[j].name; f.type = types[j].name;
f.size = types[j].size; f.size = types[j].size;
j = stream.GetI2(); j = stream.GetI2();
if (j >= names.size()) { if (j >= names.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid name index in structure field ", j, "BlenderDNA: Invalid name index in structure field ", j,
" (there are only ", names.size(), " entries)" " (there are only ", names.size(), " entries)"
)); ));
} }
f.name = names[j]; f.name = names[j];
f.flags = 0u; f.flags = 0u;
// pointers always specify the size of the pointee instead of their own. // pointers always specify the size of the pointee instead of their own.
// The pointer asterisk remains a property of the lookup name. // The pointer asterisk remains a property of the lookup name.
if (f.name[0] == '*') { if (f.name[0] == '*') {
f.size = db.i64bit ? 8 : 4; f.size = db.i64bit ? 8 : 4;
f.flags |= FieldFlag_Pointer; f.flags |= FieldFlag_Pointer;
} }
// arrays, however, specify the size of a single element so we // arrays, however, specify the size of a single element so we
// need to parse the (possibly multi-dimensional) array declaration // need to parse the (possibly multi-dimensional) array declaration
// in order to obtain the actual size of the array in the file. // 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 // Also we need to alter the lookup name to include no array
// brackets anymore or size fixup won't work (if our size does // brackets anymore or size fixup won't work (if our size does
// not match the size read from the DNA). // not match the size read from the DNA).
if (*f.name.rbegin() == ']') { if (*f.name.rbegin() == ']') {
const std::string::size_type rb = f.name.find('['); const std::string::size_type rb = f.name.find('[');
if (rb == std::string::npos) { if (rb == std::string::npos) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Encountered invalid array declaration ", "BlenderDNA: Encountered invalid array declaration ",
f.name f.name
)); ));
} }
f.flags |= FieldFlag_Array; f.flags |= FieldFlag_Array;
DNA::ExtractArraySize(f.name,f.array_sizes); DNA::ExtractArraySize(f.name,f.array_sizes);
f.name = f.name.substr(0,rb); f.name = f.name.substr(0,rb);
f.size *= f.array_sizes[0] * f.array_sizes[1]; f.size *= f.array_sizes[0] * f.array_sizes[1];
} }
// maintain separate indexes // maintain separate indexes
s.indices[f.name] = s.fields.size()-1; s.indices[f.name] = s.fields.size()-1;
offset += f.size; offset += f.size;
} }
s.size = offset; s.size = offset;
} }
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
" structures with totally ",fields," fields")); " structures with totally ",fields," fields"));
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
dna.DumpToFile(); dna.DumpToFile();
#endif #endif
dna.AddPrimitiveStructures(); dna.AddPrimitiveStructures();
dna.RegisterConverters(); dna.RegisterConverters();
} }
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
#include <fstream> #include <fstream>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNA :: DumpToFile() void DNA :: DumpToFile()
{ {
// we dont't bother using the VFS here for this is only for debugging. // we dont't bother using the VFS here for this is only for debugging.
// (and all your bases are belong to us). // (and all your bases are belong to us).
std::ofstream f("dna.txt"); std::ofstream f("dna.txt");
if (f.fail()) { if (f.fail()) {
DefaultLogger::get()->error("Could not dump dna to dna.txt"); DefaultLogger::get()->error("Could not dump dna to dna.txt");
return; return;
} }
f << "Field format: type name offset size" << "\n"; f << "Field format: type name offset size" << "\n";
f << "Structure format: name size" << "\n"; f << "Structure format: name size" << "\n";
for_each(const Structure& s, structures) { for_each(const Structure& s, structures) {
f << s.name << " " << s.size << "\n\n"; f << s.name << " " << s.size << "\n\n";
for_each(const Field& ff, s.fields) { for_each(const Field& ff, s.fields) {
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl; f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
} }
f << std::endl; f << std::endl;
} }
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
} }
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/*static*/ void DNA :: ExtractArraySize( /*static*/ void DNA :: ExtractArraySize(
const std::string& out, const std::string& out,
size_t array_sizes[2] size_t array_sizes[2]
) )
{ {
array_sizes[0] = array_sizes[1] = 1; array_sizes[0] = array_sizes[1] = 1;
std::string::size_type pos = out.find('['); std::string::size_type pos = out.find('[');
if (pos++ == std::string::npos) { if (pos++ == std::string::npos) {
return; return;
} }
array_sizes[0] = strtoul10(&out[pos]); array_sizes[0] = strtoul10(&out[pos]);
pos = out.find('[',pos); pos = out.find('[',pos);
if (pos++ == std::string::npos) { if (pos++ == std::string::npos) {
return; return;
} }
array_sizes[1] = strtoul10(&out[pos]); array_sizes[1] = strtoul10(&out[pos]);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure( boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
const Structure& structure, const Structure& structure,
const FileDatabase& db const FileDatabase& db
) const ) const
{ {
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name); std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
if (it == converters.end()) { if (it == converters.end()) {
return boost::shared_ptr< ElemBase >(); return boost::shared_ptr< ElemBase >();
} }
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))(); boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
(structure.*((*it).second.second))(ret,db); (structure.*((*it).second.second))(ret,db);
return ret; return ret;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
DNA::FactoryPair DNA :: GetBlobToStructureConverter( DNA::FactoryPair DNA :: GetBlobToStructureConverter(
const Structure& structure, const Structure& structure,
const FileDatabase& /*db*/ const FileDatabase& /*db*/
) const ) const
{ {
std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name); std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
return it == converters.end() ? FactoryPair() : (*it).second; return it == converters.end() ? FactoryPair() : (*it).second;
} }
// basing on http://www.blender.org/development/architecture/notes-on-sdna/ // basing on http://www.blender.org/development/architecture/notes-on-sdna/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNA :: AddPrimitiveStructures() void DNA :: AddPrimitiveStructures()
{ {
// NOTE: these are just dummies. Their presence enforces // NOTE: these are just dummies. Their presence enforces
// Structure::Convert<target_type> to be called on these // Structure::Convert<target_type> to be called on these
// empty structures. These converters are special // empty structures. These converters are special
// overloads which scan the name of the structure and // overloads which scan the name of the structure and
// perform the required data type conversion if one // perform the required data type conversion if one
// of these special names is found in the structure // of these special names is found in the structure
// in question. // in question.
indices["int"] = structures.size(); indices["int"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "int"; structures.back().name = "int";
structures.back().size = 4; structures.back().size = 4;
indices["short"] = structures.size(); indices["short"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "short"; structures.back().name = "short";
structures.back().size = 2; structures.back().size = 2;
indices["char"] = structures.size(); indices["char"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "char"; structures.back().name = "char";
structures.back().size = 1; structures.back().size = 1;
indices["float"] = structures.size(); indices["float"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "float"; structures.back().name = "float";
structures.back().size = 4; structures.back().size = 4;
indices["double"] = structures.size(); indices["double"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "double"; structures.back().name = "double";
structures.back().size = 8; structures.back().size = 8;
// no long, seemingly. // no long, seemingly.
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SectionParser :: Next() void SectionParser :: Next()
{ {
stream.SetCurrentPos(current.start + current.size); stream.SetCurrentPos(current.start + current.size);
const char tmp[] = { const char tmp[] = {
stream.GetI1(), stream.GetI1(),
stream.GetI1(), stream.GetI1(),
stream.GetI1(), stream.GetI1(),
stream.GetI1() stream.GetI1()
}; };
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1); current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
current.size = stream.GetI4(); current.size = stream.GetI4();
current.address.val = ptr64 ? stream.GetU8() : stream.GetU4(); current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
current.dna_index = stream.GetI4(); current.dna_index = stream.GetI4();
current.num = stream.GetI4(); current.num = stream.GetI4();
current.start = stream.GetCurrentPos(); current.start = stream.GetCurrentPos();
if (stream.GetRemainingSizeToLimit() < current.size) { if (stream.GetRemainingSizeToLimit() < current.size) {
throw DeadlyImportError("BLEND: invalid size of file block"); throw DeadlyImportError("BLEND: invalid size of file block");
} }
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
DefaultLogger::get()->debug(current.id); DefaultLogger::get()->debug(current.id);
#endif #endif
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,204 +1,204 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderIntermediate.h /** @file BlenderIntermediate.h
* @brief Internal utility structures for the BlenderLoader. It also serves * @brief Internal utility structures for the BlenderLoader. It also serves
* as master include file for the whole (internal) Blender subsystem. * as master include file for the whole (internal) Blender subsystem.
*/ */
#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H #ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
#define INCLUDED_AI_BLEND_INTERMEDIATE_H #define INCLUDED_AI_BLEND_INTERMEDIATE_H
#include "BlenderLoader.h" #include "BlenderLoader.h"
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "BlenderScene.h" #include "BlenderScene.h"
#include "BlenderSceneGen.h" #include "BlenderSceneGen.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <deque> #include <deque>
#include "./../include/assimp/material.h" #include "./../include/assimp/material.h"
struct aiTexture; struct aiTexture;
#define for_each(x,y) BOOST_FOREACH(x,y) #define for_each(x,y) BOOST_FOREACH(x,y)
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */ /** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template <template <typename,typename> class TCLASS, typename T> template <template <typename,typename> class TCLASS, typename T>
struct TempArray { struct TempArray {
typedef TCLASS< T*,std::allocator<T*> > mywrap; typedef TCLASS< T*,std::allocator<T*> > mywrap;
TempArray() { TempArray() {
} }
~TempArray () { ~TempArray () {
for_each(T* elem, arr) { for_each(T* elem, arr) {
delete elem; delete elem;
} }
} }
void dismiss() { void dismiss() {
arr.clear(); arr.clear();
} }
mywrap* operator -> () { mywrap* operator -> () {
return &arr; return &arr;
} }
operator mywrap& () { operator mywrap& () {
return arr; return arr;
} }
operator const mywrap& () const { operator const mywrap& () const {
return arr; return arr;
} }
mywrap& get () { mywrap& get () {
return arr; return arr;
} }
const mywrap& get () const { const mywrap& get () const {
return arr; return arr;
} }
T* operator[] (size_t idx) const { T* operator[] (size_t idx) const {
return arr[idx]; return arr[idx];
} }
T*& operator[] (size_t idx) { T*& operator[] (size_t idx) {
return arr[idx]; return arr[idx];
} }
private: private:
// no copy semantics // no copy semantics
void operator= (const TempArray&) { void operator= (const TempArray&) {
} }
TempArray(const TempArray& arr) { TempArray(const TempArray& arr) {
} }
private: private:
mywrap arr; mywrap arr;
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable:4351) # pragma warning(disable:4351)
#endif #endif
struct ObjectCompare { struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const { bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1; return strcmp(left->id.name, right->id.name) == -1;
} }
}; };
// When keeping objects in sets, sort them by their name. // When keeping objects in sets, sort them by their name.
typedef std::set<const Object*, ObjectCompare> ObjectSet; typedef std::set<const Object*, ObjectCompare> ObjectSet;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** ConversionData acts as intermediate storage location for /** ConversionData acts as intermediate storage location for
* the various ConvertXXX routines in BlenderImporter.*/ * the various ConvertXXX routines in BlenderImporter.*/
// -------------------------------------------------------------------- // --------------------------------------------------------------------
struct ConversionData struct ConversionData
{ {
ConversionData(const FileDatabase& db) ConversionData(const FileDatabase& db)
: sentinel_cnt() : sentinel_cnt()
, next_texture() , next_texture()
, db(db) , db(db)
{} {}
struct ObjectCompare { struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const { bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1; return strcmp(left->id.name, right->id.name) == -1;
} }
}; };
ObjectSet objects; ObjectSet objects;
TempArray <std::vector, aiMesh> meshes; TempArray <std::vector, aiMesh> meshes;
TempArray <std::vector, aiCamera> cameras; TempArray <std::vector, aiCamera> cameras;
TempArray <std::vector, aiLight> lights; TempArray <std::vector, aiLight> lights;
TempArray <std::vector, aiMaterial> materials; TempArray <std::vector, aiMaterial> materials;
TempArray <std::vector, aiTexture> textures; TempArray <std::vector, aiTexture> textures;
// set of all materials referenced by at least one mesh in the scene // set of all materials referenced by at least one mesh in the scene
std::deque< boost::shared_ptr< Material > > materials_raw; std::deque< boost::shared_ptr< Material > > materials_raw;
// counter to name sentinel textures inserted as substitutes for procedural textures. // counter to name sentinel textures inserted as substitutes for procedural textures.
unsigned int sentinel_cnt; unsigned int sentinel_cnt;
// next texture ID for each texture type, respectively // next texture ID for each texture type, respectively
unsigned int next_texture[aiTextureType_UNKNOWN+1]; unsigned int next_texture[aiTextureType_UNKNOWN+1];
// original file data // original file data
const FileDatabase& db; const FileDatabase& db;
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(default:4351) # pragma warning(default:4351)
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline const char* GetTextureTypeDisplayString(Tex::Type t) inline const char* GetTextureTypeDisplayString(Tex::Type t)
{ {
switch (t) { switch (t) {
case Tex::Type_CLOUDS : return "Clouds"; case Tex::Type_CLOUDS : return "Clouds";
case Tex::Type_WOOD : return "Wood"; case Tex::Type_WOOD : return "Wood";
case Tex::Type_MARBLE : return "Marble"; case Tex::Type_MARBLE : return "Marble";
case Tex::Type_MAGIC : return "Magic"; case Tex::Type_MAGIC : return "Magic";
case Tex::Type_BLEND : return "Blend"; case Tex::Type_BLEND : return "Blend";
case Tex::Type_STUCCI : return "Stucci"; case Tex::Type_STUCCI : return "Stucci";
case Tex::Type_NOISE : return "Noise"; case Tex::Type_NOISE : return "Noise";
case Tex::Type_PLUGIN : return "Plugin"; case Tex::Type_PLUGIN : return "Plugin";
case Tex::Type_MUSGRAVE : return "Musgrave"; case Tex::Type_MUSGRAVE : return "Musgrave";
case Tex::Type_VORONOI : return "Voronoi"; case Tex::Type_VORONOI : return "Voronoi";
case Tex::Type_DISTNOISE : return "DistortedNoise"; case Tex::Type_DISTNOISE : return "DistortedNoise";
case Tex::Type_ENVMAP : return "EnvMap"; case Tex::Type_ENVMAP : return "EnvMap";
case Tex::Type_IMAGE : return "Image"; case Tex::Type_IMAGE : return "Image";
default: default:
break; break;
} }
return "<Unknown>"; return "<Unknown>";
} }
} // ! Blender } // ! Blender
} // ! Assimp } // ! Assimp
#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H #endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,230 +1,230 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderLoader.h /** @file BlenderLoader.h
* @brief Declaration of the Blender 3D (*.blend) importer class. * @brief Declaration of the Blender 3D (*.blend) importer class.
*/ */
#ifndef INCLUDED_AI_BLEND_LOADER_H #ifndef INCLUDED_AI_BLEND_LOADER_H
#define INCLUDED_AI_BLEND_LOADER_H #define INCLUDED_AI_BLEND_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
#include "LogAux.h" #include "LogAux.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
struct aiNode; struct aiNode;
struct aiMesh; struct aiMesh;
struct aiLight; struct aiLight;
struct aiCamera; struct aiCamera;
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
// BlenderDNA.h // BlenderDNA.h
namespace Blender { namespace Blender {
class FileDatabase; class FileDatabase;
struct ElemBase; struct ElemBase;
} }
// BlenderScene.h // BlenderScene.h
namespace Blender { namespace Blender {
struct Scene; struct Scene;
struct Object; struct Object;
struct Mesh; struct Mesh;
struct Camera; struct Camera;
struct Lamp; struct Lamp;
struct MTex; struct MTex;
struct Image; struct Image;
struct Material; struct Material;
} }
// BlenderIntermediate.h // BlenderIntermediate.h
namespace Blender { namespace Blender {
struct ConversionData; struct ConversionData;
template <template <typename,typename> class TCLASS, typename T> struct TempArray; template <template <typename,typename> class TCLASS, typename T> struct TempArray;
} }
// BlenderModifier.h // BlenderModifier.h
namespace Blender { namespace Blender {
class BlenderModifierShowcase; class BlenderModifierShowcase;
class BlenderModifier; class BlenderModifier;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Load blenders official binary format. The actual file structure (the `DNA` how they /** 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 * call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */ * conversion from intermediate format to aiScene. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{ {
public: public:
BlenderImporter(); BlenderImporter();
~BlenderImporter(); ~BlenderImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, bool CanRead( const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void GetExtensionList(std::set<std::string>& app); void GetExtensionList(std::set<std::string>& app);
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, void InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
// -------------------- // --------------------
void ParseBlendFile(Blender::FileDatabase& out, void ParseBlendFile(Blender::FileDatabase& out,
boost::shared_ptr<IOStream> stream boost::shared_ptr<IOStream> stream
); );
// -------------------- // --------------------
void ExtractScene(Blender::Scene& out, void ExtractScene(Blender::Scene& out,
const Blender::FileDatabase& file const Blender::FileDatabase& file
); );
// -------------------- // --------------------
void ConvertBlendFile(aiScene* out, void ConvertBlendFile(aiScene* out,
const Blender::Scene& in, const Blender::Scene& in,
const Blender::FileDatabase& file const Blender::FileDatabase& file
); );
private: private:
// -------------------- // --------------------
aiNode* ConvertNode(const Blender::Scene& in, aiNode* ConvertNode(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
Blender::ConversionData& conv_info, Blender::ConversionData& conv_info,
const aiMatrix4x4& parentTransform const aiMatrix4x4& parentTransform
); );
// -------------------- // --------------------
void ConvertMesh(const Blender::Scene& in, void ConvertMesh(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Mesh* mesh, const Blender::Mesh* mesh,
Blender::ConversionData& conv_data, Blender::ConversionData& conv_data,
Blender::TempArray<std::vector,aiMesh>& temp Blender::TempArray<std::vector,aiMesh>& temp
); );
// -------------------- // --------------------
aiLight* ConvertLight(const Blender::Scene& in, aiLight* ConvertLight(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Lamp* mesh, const Blender::Lamp* mesh,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
aiCamera* ConvertCamera(const Blender::Scene& in, aiCamera* ConvertCamera(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Camera* mesh, const Blender::Camera* mesh,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
void BuildMaterials( void BuildMaterials(
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
) ; ) ;
// -------------------- // --------------------
void ResolveTexture( void ResolveTexture(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
void ResolveImage( void ResolveImage(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
const Blender::Image* img, const Blender::Image* img,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
void AddSentinelTexture( void AddSentinelTexture(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
private: // static stuff, mostly logging and error reporting. private: // static stuff, mostly logging and error reporting.
// -------------------- // --------------------
static void CheckActualType(const Blender::ElemBase* dt, static void CheckActualType(const Blender::ElemBase* dt,
const char* check const char* check
); );
// -------------------- // --------------------
static void NotSupportedObjectType(const Blender::Object* obj, static void NotSupportedObjectType(const Blender::Object* obj,
const char* type const char* type
); );
private: private:
Blender::BlenderModifierShowcase* modifier_cache; Blender::BlenderModifierShowcase* modifier_cache;
}; // !class BlenderImporter }; // !class BlenderImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC #endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,328 +1,328 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderModifier.cpp /** @file BlenderModifier.cpp
* @brief Implementation of some blender modifiers (i.e subdivision, mirror). * @brief Implementation of some blender modifiers (i.e subdivision, mirror).
*/ */
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderModifier.h" #include "BlenderModifier.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "Subdivision.h" #include "Subdivision.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <boost/pointer_cast.hpp> #include <boost/pointer_cast.hpp>
#include <functional> #include <functional>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
template <typename T> BlenderModifier* god() { template <typename T> BlenderModifier* god() {
return new T(); return new T();
} }
// add all available modifiers here // add all available modifiers here
typedef BlenderModifier* (*fpCreateModifier)(); typedef BlenderModifier* (*fpCreateModifier)();
static const fpCreateModifier creators[] = { static const fpCreateModifier creators[] = {
&god<BlenderModifier_Mirror>, &god<BlenderModifier_Mirror>,
&god<BlenderModifier_Subdivision>, &god<BlenderModifier_Subdivision>,
NULL // sentinel NULL // sentinel
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// just testing out some new macros to simplify logging // just testing out some new macros to simplify logging
#define ASSIMP_LOG_WARN_F(string,...)\ #define ASSIMP_LOG_WARN_F(string,...)\
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_ERROR_F(string,...)\ #define ASSIMP_LOG_ERROR_F(string,...)\
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_DEBUG_F(string,...)\ #define ASSIMP_LOG_DEBUG_F(string,...)\
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_INFO_F(string,...)\ #define ASSIMP_LOG_INFO_F(string,...)\
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_WARN(string)\ #define ASSIMP_LOG_WARN(string)\
DefaultLogger::get()->warn(string) DefaultLogger::get()->warn(string)
#define ASSIMP_LOG_ERROR(string)\ #define ASSIMP_LOG_ERROR(string)\
DefaultLogger::get()->error(string) DefaultLogger::get()->error(string)
#define ASSIMP_LOG_DEBUG(string)\ #define ASSIMP_LOG_DEBUG(string)\
DefaultLogger::get()->debug(string) DefaultLogger::get()->debug(string)
#define ASSIMP_LOG_INFO(string)\ #define ASSIMP_LOG_INFO(string)\
DefaultLogger::get()->info(string) DefaultLogger::get()->info(string)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase struct SharedModifierData : ElemBase
{ {
ModifierData modifier; ModifierData modifier;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object ) void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
{ {
size_t cnt = 0u, ful = 0u; size_t cnt = 0u, ful = 0u;
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before // 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 // 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 // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
// structures is at offset sizeof(vftable) with no padding. // structures is at offset sizeof(vftable) with no padding.
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() ); 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) { for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
ai_assert(cur->dna_type); ai_assert(cur->dna_type);
const Structure* s = conv_data.db.dna.Get( cur->dna_type ); const Structure* s = conv_data.db.dna.Get( cur->dna_type );
if (!s) { if (!s) {
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type); ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
continue; continue;
} }
// this is a common trait of all XXXMirrorData structures in BlenderDNA // this is a common trait of all XXXMirrorData structures in BlenderDNA
const Field* f = s->Get("modifier"); const Field* f = s->Get("modifier");
if (!f || f->offset != 0) { if (!f || f->offset != 0) {
ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0"); ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
continue; continue;
} }
s = conv_data.db.dna.Get( f->type ); s = conv_data.db.dna.Get( f->type );
if (!s || s->name != "ModifierData") { if (!s || s->name != "ModifierData") {
ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member"); ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
continue; continue;
} }
// now, we can be sure that we should be fine to dereference *cur* as // now, we can be sure that we should be fine to dereference *cur* as
// ModifierData (with the above note). // ModifierData (with the above note).
const ModifierData& dat = cur->modifier; const ModifierData& dat = cur->modifier;
const fpCreateModifier* curgod = creators; const fpCreateModifier* curgod = creators;
std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end(); std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
if (curmod == endmod) { if (curmod == endmod) {
cached_modifiers->push_back((*curgod)()); cached_modifiers->push_back((*curgod)());
endmod = cached_modifiers->end(); endmod = cached_modifiers->end();
curmod = endmod-1; curmod = endmod-1;
} }
BlenderModifier* const modifier = *curmod; BlenderModifier* const modifier = *curmod;
if(modifier->IsActive(dat)) { if(modifier->IsActive(dat)) {
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object); modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
cnt++; cnt++;
curgod = NULL; curgod = NULL;
break; break;
} }
} }
if (curgod) { if (curgod) {
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name); 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 // 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 // object, we still can't say whether our modifier implementations were
// able to fully do their job. // able to fully do their job.
if (ful) { if (ful) {
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name, ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
"`, check log messages above for errors"); "`, check log messages above for errors");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin) bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
{ {
return modin.type == ModifierData::eModifierType_Mirror; return modin.type == ModifierData::eModifierType_Mirror;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& orig_object ) const Object& orig_object )
{ {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier); const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror); ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes); conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ... // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
// take all input meshes and clone them // take all input meshes and clone them
for (unsigned int i = 0; i < out.mNumMeshes; ++i) { for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
aiMesh* mesh; aiMesh* mesh;
SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]); SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f; 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 ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f; const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
if (mir.mirror_ob) { 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] ); 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) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i]; aiVector3D& v = mesh->mVertices[i];
v.x = center.x + xs*(center.x - v.x); v.x = center.x + xs*(center.x - v.x);
v.y = center.y + ys*(center.y - v.y); v.y = center.y + ys*(center.y - v.y);
v.z = center.z + zs*(center.z - v.z); v.z = center.z + zs*(center.z - v.z);
} }
} }
else { else {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i]; aiVector3D& v = mesh->mVertices[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mNormals) { if (mesh->mNormals) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mNormals[i]; aiVector3D& v = mesh->mNormals[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mTangents) { if (mesh->mTangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTangents[i]; aiVector3D& v = mesh->mTangents[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mBitangents) { if (mesh->mBitangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mBitangents[i]; aiVector3D& v = mesh->mBitangents[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f; 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; 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 n = 0; mesh->HasTextureCoords(n); ++n) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTextureCoords[n][i]; aiVector3D& v = mesh->mTextureCoords[n][i];
v.x *= us;v.y *= vs; v.x *= us;v.y *= vs;
} }
} }
// Only reverse the winding order if an odd number of axes were mirrored. // Only reverse the winding order if an odd number of axes were mirrored.
if (xs * ys * zs < 0) { if (xs * ys * zs < 0) {
for( unsigned int i = 0; i < mesh->mNumFaces; i++) { for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace& face = mesh->mFaces[i]; aiFace& face = mesh->mFaces[i];
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi) for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]); std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
} }
} }
conv_data.meshes->push_back(mesh); conv_data.meshes->push_back(mesh);
} }
unsigned int* nind = new unsigned int[out.mNumMeshes*2]; unsigned int* nind = new unsigned int[out.mNumMeshes*2];
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind); std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes, std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes)); std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
delete[] out.mMeshes; delete[] out.mMeshes;
out.mMeshes = nind; out.mMeshes = nind;
out.mNumMeshes *= 2; out.mNumMeshes *= 2;
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `", ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
orig_object.id.name,"`"); orig_object.id.name,"`");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin) bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
{ {
return modin.type == ModifierData::eModifierType_Subsurf; return modin.type == ModifierData::eModifierType_Subsurf;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& orig_object ) const Object& orig_object )
{ {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier); const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf); ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
Subdivider::Algorithm algo; Subdivider::Algorithm algo;
switch (mir.subdivType) switch (mir.subdivType)
{ {
case SubsurfModifierData::TYPE_CatmullClarke: case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE; algo = Subdivider::CATMULL_CLARKE;
break; break;
case SubsurfModifierData::TYPE_Simple: case SubsurfModifierData::TYPE_Simple:
ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke"); ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
algo = Subdivider::CATMULL_CLARKE; algo = Subdivider::CATMULL_CLARKE;
break; break;
default: default:
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType); ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
return; return;
}; };
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo)); boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
ai_assert(subd); ai_assert(subd);
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes]; aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[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); subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes); std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `", ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
orig_object.id.name,"`"); orig_object.id.name,"`");
} }
#endif #endif

View File

@ -1,155 +1,155 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderModifier.h /** @file BlenderModifier.h
* @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror) * @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
*/ */
#ifndef INCLUDED_AI_BLEND_MODIFIER_H #ifndef INCLUDED_AI_BLEND_MODIFIER_H
#define INCLUDED_AI_BLEND_MODIFIER_H #define INCLUDED_AI_BLEND_MODIFIER_H
#include "BlenderIntermediate.h" #include "BlenderIntermediate.h"
#include "TinyFormatter.h" #include "TinyFormatter.h"
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so /** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
* they should be stateless and not try to cache model data. */ * they should be stateless and not try to cache model data. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier class BlenderModifier
{ {
public: public:
virtual ~BlenderModifier() { virtual ~BlenderModifier() {
} }
public: public:
// -------------------- // --------------------
/** Check if *this* modifier is active, given a ModifierData& block.*/ /** Check if *this* modifier is active, given a ModifierData& block.*/
virtual bool IsActive( const ModifierData& /*modin*/) { virtual bool IsActive( const ModifierData& /*modin*/) {
return false; return false;
} }
// -------------------- // --------------------
/** Apply the modifier to a given output node. The original data used /** Apply the modifier to a given output node. The original data used
* to construct the node is given as well. Not called unless IsActive() * to construct the node is given as well. Not called unless IsActive()
* was called and gave positive response. */ * was called and gave positive response. */
virtual void DoIt(aiNode& /*out*/, virtual void DoIt(aiNode& /*out*/,
ConversionData& /*conv_data*/, ConversionData& /*conv_data*/,
const ElemBase& orig_modifier, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& /*orig_object*/ const Object& /*orig_object*/
) { ) {
DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type)); DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
return; return;
} }
}; };
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Manage all known modifiers and instance and apply them if necessary */ /** Manage all known modifiers and instance and apply them if necessary */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifierShowcase class BlenderModifierShowcase
{ {
public: public:
// -------------------- // --------------------
/** Apply all requested modifiers provided we support them. */ /** Apply all requested modifiers provided we support them. */
void ApplyModifiers(aiNode& out, void ApplyModifiers(aiNode& out,
ConversionData& conv_data, ConversionData& conv_data,
const Scene& in, const Scene& in,
const Object& orig_object const Object& orig_object
); );
private: private:
TempArray< std::vector,BlenderModifier > cached_modifiers; TempArray< std::vector,BlenderModifier > cached_modifiers;
}; };
// MODIFIERS // MODIFIERS
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Mirror modifier. Status: implemented. */ /** Mirror modifier. Status: implemented. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Mirror : public BlenderModifier class BlenderModifier_Mirror : public BlenderModifier
{ {
public: public:
// -------------------- // --------------------
virtual bool IsActive( const ModifierData& modin); virtual bool IsActive( const ModifierData& modin);
// -------------------- // --------------------
virtual void DoIt(aiNode& out, virtual void DoIt(aiNode& out,
ConversionData& conv_data, ConversionData& conv_data,
const ElemBase& orig_modifier, const ElemBase& orig_modifier,
const Scene& in, const Scene& in,
const Object& orig_object const Object& orig_object
) ; ) ;
}; };
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Subdivision modifier. Status: dummy. */ /** Subdivision modifier. Status: dummy. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Subdivision : public BlenderModifier class BlenderModifier_Subdivision : public BlenderModifier
{ {
public: public:
// -------------------- // --------------------
virtual bool IsActive( const ModifierData& modin); virtual bool IsActive( const ModifierData& modin);
// -------------------- // --------------------
virtual void DoIt(aiNode& out, virtual void DoIt(aiNode& out,
ConversionData& conv_data, ConversionData& conv_data,
const ElemBase& orig_modifier, const ElemBase& orig_modifier,
const Scene& in, const Scene& in,
const Object& orig_object const Object& orig_object
) ; ) ;
}; };
}} }}
#endif // !INCLUDED_AI_BLEND_MODIFIER_H #endif // !INCLUDED_AI_BLEND_MODIFIER_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,256 +1,256 @@
/* /*
Open Asset Import Library (ASSIMP) Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development Team Copyright (c) 2006-2010, ASSIMP Development Team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its * Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the ASSIMP Development Team. written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderSceneGen.h /** @file BlenderSceneGen.h
* @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
*/ */
#ifndef INCLUDED_AI_BLEND_SCENEGEN_H #ifndef INCLUDED_AI_BLEND_SCENEGEN_H
#define INCLUDED_AI_BLEND_SCENEGEN_H #define INCLUDED_AI_BLEND_SCENEGEN_H
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "BlenderScene.h" #include "BlenderScene.h"
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
template <> void Structure :: Convert<Object> ( template <> void Structure :: Convert<Object> (
Object& dest, Object& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Group> ( template <> void Structure :: Convert<Group> (
Group& dest, Group& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTex> ( template <> void Structure :: Convert<MTex> (
MTex& dest, MTex& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<TFace> ( template <> void Structure :: Convert<TFace> (
TFace& dest, TFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<SubsurfModifierData> ( template <> void Structure :: Convert<SubsurfModifierData> (
SubsurfModifierData& dest, SubsurfModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MFace> ( template <> void Structure :: Convert<MFace> (
MFace& dest, MFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Lamp> ( template <> void Structure :: Convert<Lamp> (
Lamp& dest, Lamp& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MDeformWeight> ( template <> void Structure :: Convert<MDeformWeight> (
MDeformWeight& dest, MDeformWeight& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<PackedFile> ( template <> void Structure :: Convert<PackedFile> (
PackedFile& dest, PackedFile& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Base> ( template <> void Structure :: Convert<Base> (
Base& dest, Base& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTFace> ( template <> void Structure :: Convert<MTFace> (
MTFace& dest, MTFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Material> ( template <> void Structure :: Convert<Material> (
Material& dest, Material& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTexPoly> ( template <> void Structure :: Convert<MTexPoly> (
MTexPoly& dest, MTexPoly& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Mesh> ( template <> void Structure :: Convert<Mesh> (
Mesh& dest, Mesh& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MDeformVert> ( template <> void Structure :: Convert<MDeformVert> (
MDeformVert& dest, MDeformVert& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<World> ( template <> void Structure :: Convert<World> (
World& dest, World& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoopCol> ( template <> void Structure :: Convert<MLoopCol> (
MLoopCol& dest, MLoopCol& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MVert> ( template <> void Structure :: Convert<MVert> (
MVert& dest, MVert& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MEdge> ( template <> void Structure :: Convert<MEdge> (
MEdge& dest, MEdge& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoopUV> ( template <> void Structure :: Convert<MLoopUV> (
MLoopUV& dest, MLoopUV& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<GroupObject> ( template <> void Structure :: Convert<GroupObject> (
GroupObject& dest, GroupObject& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ListBase> ( template <> void Structure :: Convert<ListBase> (
ListBase& dest, ListBase& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoop> ( template <> void Structure :: Convert<MLoop> (
MLoop& dest, MLoop& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ModifierData> ( template <> void Structure :: Convert<ModifierData> (
ModifierData& dest, ModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ID> ( template <> void Structure :: Convert<ID> (
ID& dest, ID& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MCol> ( template <> void Structure :: Convert<MCol> (
MCol& dest, MCol& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MPoly> ( template <> void Structure :: Convert<MPoly> (
MPoly& dest, MPoly& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Scene> ( template <> void Structure :: Convert<Scene> (
Scene& dest, Scene& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Library> ( template <> void Structure :: Convert<Library> (
Library& dest, Library& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Tex> ( template <> void Structure :: Convert<Tex> (
Tex& dest, Tex& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Camera> ( template <> void Structure :: Convert<Camera> (
Camera& dest, Camera& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MirrorModifierData> ( template <> void Structure :: Convert<MirrorModifierData> (
MirrorModifierData& dest, MirrorModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Image> ( template <> void Structure :: Convert<Image> (
Image& dest, Image& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
} }
} }
#endif #endif

View File

@ -1,337 +1,337 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Provides cheat implementations for IOSystem and IOStream to /** @file Provides cheat implementations for IOSystem and IOStream to
* redirect exporter output to a blob chain.*/ * redirect exporter output to a blob chain.*/
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED #ifndef AI_BLOBIOSYSTEM_H_INCLUDED
#define AI_BLOBIOSYSTEM_H_INCLUDED #define AI_BLOBIOSYSTEM_H_INCLUDED
#include "./../include/assimp/IOStream.hpp" #include "./../include/assimp/IOStream.hpp"
#include "./../include/assimp/cexport.h" #include "./../include/assimp/cexport.h"
#include "./../include/assimp/IOSystem.hpp" #include "./../include/assimp/IOSystem.hpp"
#include "./../include/assimp/DefaultLogger.hpp" #include "./../include/assimp/DefaultLogger.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <stdint.h> #include <stdint.h>
#include <set> #include <set>
#include <vector> #include <vector>
namespace Assimp { namespace Assimp {
class BlobIOSystem; class BlobIOSystem;
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
/** Redirect IOStream to a blob */ /** Redirect IOStream to a blob */
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
class BlobIOStream : public IOStream class BlobIOStream : public IOStream
{ {
public: public:
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096) BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
: buffer() : buffer()
, cur_size() , cur_size()
, file_size() , file_size()
, cursor() , cursor()
, initial(initial) , initial(initial)
, file(file) , file(file)
, creator(creator) , creator(creator)
{ {
} }
virtual ~BlobIOStream(); virtual ~BlobIOStream();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
aiExportDataBlob* GetBlob() aiExportDataBlob* GetBlob()
{ {
aiExportDataBlob* blob = new aiExportDataBlob(); aiExportDataBlob* blob = new aiExportDataBlob();
blob->size = file_size; blob->size = file_size;
blob->data = buffer; blob->data = buffer;
buffer = NULL; buffer = NULL;
return blob; return blob;
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Read( void *, virtual size_t Read( void *,
size_t, size_t,
size_t ) size_t )
{ {
return 0; return 0;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Write(const void* pvBuffer, virtual size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
pSize *= pCount; pSize *= pCount;
if (cursor + pSize > cur_size) { if (cursor + pSize > cur_size) {
Grow(cursor + pSize); Grow(cursor + pSize);
} }
memcpy(buffer+cursor, pvBuffer, pSize); memcpy(buffer+cursor, pvBuffer, pSize);
cursor += pSize; cursor += pSize;
file_size = std::max(file_size,cursor); file_size = std::max(file_size,cursor);
return pCount; return pCount;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual aiReturn Seek(size_t pOffset, virtual aiReturn Seek(size_t pOffset,
aiOrigin pOrigin) aiOrigin pOrigin)
{ {
switch(pOrigin) switch(pOrigin)
{ {
case aiOrigin_CUR: case aiOrigin_CUR:
cursor += pOffset; cursor += pOffset;
break; break;
case aiOrigin_END: case aiOrigin_END:
cursor = file_size - pOffset; cursor = file_size - pOffset;
break; break;
case aiOrigin_SET: case aiOrigin_SET:
cursor = pOffset; cursor = pOffset;
break; break;
default: default:
return AI_FAILURE; return AI_FAILURE;
} }
if (cursor > file_size) { if (cursor > file_size) {
Grow(cursor); Grow(cursor);
} }
file_size = std::max(cursor,file_size); file_size = std::max(cursor,file_size);
return AI_SUCCESS; return AI_SUCCESS;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Tell() const virtual size_t Tell() const
{ {
return cursor; return cursor;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t FileSize() const virtual size_t FileSize() const
{ {
return file_size; return file_size;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Flush() virtual void Flush()
{ {
// ignore // ignore
} }
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Grow(size_t need = 0) void Grow(size_t need = 0)
{ {
// 1.5 and phi are very heap-friendly growth factors (the first // 1.5 and phi are very heap-friendly growth factors (the first
// allows for frequent re-use of heap blocks, the second // allows for frequent re-use of heap blocks, the second
// forms a fibonacci sequence with similar characteristics - // forms a fibonacci sequence with similar characteristics -
// since this heavily depends on the heap implementation // since this heavily depends on the heap implementation
// and other factors as well, i'll just go with 1.5 since // and other factors as well, i'll just go with 1.5 since
// it is quicker to compute). // it is quicker to compute).
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
const uint8_t* const old = buffer; const uint8_t* const old = buffer;
buffer = new uint8_t[new_size]; buffer = new uint8_t[new_size];
if (old) { if (old) {
memcpy(buffer,old,cur_size); memcpy(buffer,old,cur_size);
delete[] old; delete[] old;
} }
cur_size = new_size; cur_size = new_size;
} }
private: private:
uint8_t* buffer; uint8_t* buffer;
size_t cur_size,file_size, cursor, initial; size_t cur_size,file_size, cursor, initial;
const std::string file; const std::string file;
BlobIOSystem* const creator; BlobIOSystem* const creator;
}; };
#define AI_BLOBIO_MAGIC "$blobfile" #define AI_BLOBIO_MAGIC "$blobfile"
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
/** Redirect IOSystem to a blob */ /** Redirect IOSystem to a blob */
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
class BlobIOSystem : public IOSystem class BlobIOSystem : public IOSystem
{ {
friend class BlobIOStream; friend class BlobIOStream;
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry; typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
public: public:
BlobIOSystem() BlobIOSystem()
{ {
} }
virtual ~BlobIOSystem() virtual ~BlobIOSystem()
{ {
BOOST_FOREACH(BlobEntry& blobby, blobs) { BOOST_FOREACH(BlobEntry& blobby, blobs) {
delete blobby.second; delete blobby.second;
} }
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const char* GetMagicFileName() const const char* GetMagicFileName() const
{ {
return AI_BLOBIO_MAGIC; return AI_BLOBIO_MAGIC;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
aiExportDataBlob* GetBlobChain() aiExportDataBlob* GetBlobChain()
{ {
// one must be the master // one must be the master
aiExportDataBlob* master = NULL, *cur; aiExportDataBlob* master = NULL, *cur;
BOOST_FOREACH(const BlobEntry& blobby, blobs) { BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.first == AI_BLOBIO_MAGIC) { if (blobby.first == AI_BLOBIO_MAGIC) {
master = blobby.second; master = blobby.second;
break; break;
} }
} }
if (!master) { if (!master) {
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly."); DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
return NULL; return NULL;
} }
master->name.Set(""); master->name.Set("");
cur = master; cur = master;
BOOST_FOREACH(const BlobEntry& blobby, blobs) { BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.second == master) { if (blobby.second == master) {
continue; continue;
} }
cur->next = blobby.second; cur->next = blobby.second;
cur = cur->next; cur = cur->next;
// extract the file extension from the file written // extract the file extension from the file written
const std::string::size_type s = blobby.first.find_first_of('.'); const std::string::size_type s = blobby.first.find_first_of('.');
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1)); cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
} }
// give up blob ownership // give up blob ownership
blobs.clear(); blobs.clear();
return master; return master;
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual bool Exists( const char* pFile) const { virtual bool Exists( const char* pFile) const {
return created.find(std::string(pFile)) != created.end(); return created.find(std::string(pFile)) != created.end();
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual char getOsSeparator() const { virtual char getOsSeparator() const {
return '/'; return '/';
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual IOStream* Open(const char* pFile, virtual IOStream* Open(const char* pFile,
const char* pMode) const char* pMode)
{ {
if (pMode[0] != 'w') { if (pMode[0] != 'w') {
return NULL; return NULL;
} }
created.insert(std::string(pFile)); created.insert(std::string(pFile));
return new BlobIOStream(this,std::string(pFile)); return new BlobIOStream(this,std::string(pFile));
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Close( IOStream* pFile) virtual void Close( IOStream* pFile)
{ {
delete pFile; delete pFile;
} }
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void OnDestruct(const std::string& filename, BlobIOStream* child) void OnDestruct(const std::string& filename, BlobIOStream* child)
{ {
// we don't know in which the files are closed, so we // we don't know in which the files are closed, so we
// can't reliably say that the first must be the master // can't reliably say that the first must be the master
// file ... // file ...
blobs.push_back( BlobEntry(filename,child->GetBlob()) ); blobs.push_back( BlobEntry(filename,child->GetBlob()) );
} }
private: private:
std::set<std::string> created; std::set<std::string> created;
std::vector< BlobEntry > blobs; std::vector< BlobEntry > blobs;
}; };
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
BlobIOStream :: ~BlobIOStream() BlobIOStream :: ~BlobIOStream()
{ {
creator->OnDestruct(file,this); creator->OnDestruct(file,this);
delete[] buffer; delete[] buffer;
} }
} // end Assimp } // end Assimp
#endif #endif

View File

@ -1,286 +1,286 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Helper class tp perform various byte oder swappings /** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */ (e.g. little to big endian) */
#ifndef AI_BYTESWAPPER_H_INC #ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC #define AI_BYTESWAPPER_H_INC
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include <stdint.h> #include <stdint.h>
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
#include <stdlib.h> #include <stdlib.h>
#endif #endif
namespace Assimp { namespace Assimp {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
/** Defines some useful byte order swap routines. /** Defines some useful byte order swap routines.
* *
* This is required to read big-endian model formats on little-endian machines, * 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. */ * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class ByteSwap class ByteSwap
{ {
ByteSwap() {} ByteSwap() {}
public: public:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap two bytes of data /** Swap two bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap2(void* _szOut) static inline void Swap2(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut); uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
*szOut = _byteswap_ushort(*szOut); *szOut = _byteswap_ushort(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[1]); std::swap(szOut[0],szOut[1]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap four bytes of data /** Swap four bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap4(void* _szOut) static inline void Swap4(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut); uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
*szOut = _byteswap_ulong(*szOut); *szOut = _byteswap_ulong(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[3]); std::swap(szOut[0],szOut[3]);
std::swap(szOut[1],szOut[2]); std::swap(szOut[1],szOut[2]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap eight bytes of data /** Swap eight bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap8(void* _szOut) static inline void Swap8(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut); uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
*szOut = _byteswap_uint64(*szOut); *szOut = _byteswap_uint64(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[7]); std::swap(szOut[0],szOut[7]);
std::swap(szOut[1],szOut[6]); std::swap(szOut[1],szOut[6]);
std::swap(szOut[2],szOut[5]); std::swap(szOut[2],szOut[5]);
std::swap(szOut[3],szOut[4]); std::swap(szOut[3],szOut[4]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap a float. Not a joke. /** ByteSwap a float. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(float* fOut) { static inline void Swap(float* fOut) {
Swap4(fOut); Swap4(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap a double. Not a joke. /** ByteSwap a double. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(double* fOut) { static inline void Swap(double* fOut) {
Swap8(fOut); Swap8(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int16t. Not a joke. /** ByteSwap an int16t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int16_t* fOut) { static inline void Swap(int16_t* fOut) {
Swap2(fOut); Swap2(fOut);
} }
static inline void Swap(uint16_t* fOut) { static inline void Swap(uint16_t* fOut) {
Swap2(fOut); Swap2(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int32t. Not a joke. /** ByteSwap an int32t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int32_t* fOut){ static inline void Swap(int32_t* fOut){
Swap4(fOut); Swap4(fOut);
} }
static inline void Swap(uint32_t* fOut){ static inline void Swap(uint32_t* fOut){
Swap4(fOut); Swap4(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int64t. Not a joke. /** ByteSwap an int64t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int64_t* fOut) { static inline void Swap(int64_t* fOut) {
Swap8(fOut); Swap8(fOut);
} }
static inline void Swap(uint64_t* fOut) { static inline void Swap(uint64_t* fOut) {
Swap8(fOut); Swap8(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
//! Templatized ByteSwap //! Templatized ByteSwap
//! \returns param tOut as swapped //! \returns param tOut as swapped
template<typename Type> template<typename Type>
static inline Type Swapped(Type tOut) static inline Type Swapped(Type tOut)
{ {
return _swapper<Type,sizeof(Type)>()(tOut); return _swapper<Type,sizeof(Type)>()(tOut);
} }
private: private:
template <typename T, size_t size> struct _swapper; template <typename T, size_t size> struct _swapper;
}; };
template <typename T> struct ByteSwap::_swapper<T,2> { template <typename T> struct ByteSwap::_swapper<T,2> {
T operator() (T tOut) { T operator() (T tOut) {
Swap2(&tOut); Swap2(&tOut);
return tOut; return tOut;
} }
}; };
template <typename T> struct ByteSwap::_swapper<T,4> { template <typename T> struct ByteSwap::_swapper<T,4> {
T operator() (T tOut) { T operator() (T tOut) {
Swap4(&tOut); Swap4(&tOut);
return tOut; return tOut;
} }
}; };
template <typename T> struct ByteSwap::_swapper<T,8> { template <typename T> struct ByteSwap::_swapper<T,8> {
T operator() (T tOut) { T operator() (T tOut) {
Swap8(&tOut); Swap8(&tOut);
return tOut; return tOut;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ByteSwap macros for BigEndian/LittleEndian support // ByteSwap macros for BigEndian/LittleEndian support
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#if (defined AI_BUILD_BIG_ENDIAN) #if (defined AI_BUILD_BIG_ENDIAN)
# define AI_LE(t) (t) # define AI_LE(t) (t)
# define AI_BE(t) ByteSwap::Swapped(t) # define AI_BE(t) ByteSwap::Swapped(t)
# define AI_LSWAP2(p) # define AI_LSWAP2(p)
# define AI_LSWAP4(p) # define AI_LSWAP4(p)
# define AI_LSWAP8(p) # define AI_LSWAP8(p)
# define AI_LSWAP2P(p) # define AI_LSWAP2P(p)
# define AI_LSWAP4P(p) # define AI_LSWAP4P(p)
# define AI_LSWAP8P(p) # define AI_LSWAP8P(p)
# define LE_NCONST const # define LE_NCONST const
# define AI_SWAP2(p) ByteSwap::Swap2(&(p)) # define AI_SWAP2(p) ByteSwap::Swap2(&(p))
# define AI_SWAP4(p) ByteSwap::Swap4(&(p)) # define AI_SWAP4(p) ByteSwap::Swap4(&(p))
# define AI_SWAP8(p) ByteSwap::Swap8(&(p)) # define AI_SWAP8(p) ByteSwap::Swap8(&(p))
# define AI_SWAP2P(p) ByteSwap::Swap2((p)) # define AI_SWAP2P(p) ByteSwap::Swap2((p))
# define AI_SWAP4P(p) ByteSwap::Swap4((p)) # define AI_SWAP4P(p) ByteSwap::Swap4((p))
# define AI_SWAP8P(p) ByteSwap::Swap8((p)) # define AI_SWAP8P(p) ByteSwap::Swap8((p))
# define BE_NCONST # define BE_NCONST
#else #else
# define AI_BE(t) (t) # define AI_BE(t) (t)
# define AI_LE(t) ByteSwap::Swapped(t) # define AI_LE(t) ByteSwap::Swapped(t)
# define AI_SWAP2(p) # define AI_SWAP2(p)
# define AI_SWAP4(p) # define AI_SWAP4(p)
# define AI_SWAP8(p) # define AI_SWAP8(p)
# define AI_SWAP2P(p) # define AI_SWAP2P(p)
# define AI_SWAP4P(p) # define AI_SWAP4P(p)
# define AI_SWAP8P(p) # define AI_SWAP8P(p)
# define BE_NCONST const # define BE_NCONST const
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p)) # define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p)) # define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p)) # define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
# define AI_LSWAP2P(p) ByteSwap::Swap2((p)) # define AI_LSWAP2P(p) ByteSwap::Swap2((p))
# define AI_LSWAP4P(p) ByteSwap::Swap4((p)) # define AI_LSWAP4P(p) ByteSwap::Swap4((p))
# define AI_LSWAP8P(p) ByteSwap::Swap8((p)) # define AI_LSWAP8P(p) ByteSwap::Swap8((p))
# define LE_NCONST # define LE_NCONST
#endif #endif
namespace Intern { namespace Intern {
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
template <typename T, bool doit> template <typename T, bool doit>
struct ByteSwapper { struct ByteSwapper {
void operator() (T* inout) { void operator() (T* inout) {
ByteSwap::Swap(inout); ByteSwap::Swap(inout);
} }
}; };
template <typename T> template <typename T>
struct ByteSwapper<T,false> { struct ByteSwapper<T,false> {
void operator() (T*) { void operator() (T*) {
} }
}; };
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
template <bool SwapEndianess, typename T, bool RuntimeSwitch> template <bool SwapEndianess, typename T, bool RuntimeSwitch>
struct Getter { struct Getter {
void operator() (T* inout, bool le) { void operator() (T* inout, bool le) {
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN
le = le; le = le;
#else #else
le = !le; le = !le;
#endif #endif
if (le) { if (le) {
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout); ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
} }
else ByteSwapper<T,false> () (inout); else ByteSwapper<T,false> () (inout);
} }
}; };
template <bool SwapEndianess, typename T> template <bool SwapEndianess, typename T>
struct Getter<SwapEndianess,T,false> { struct Getter<SwapEndianess,T,false> {
void operator() (T* inout, bool /*le*/) { void operator() (T* inout, bool /*le*/) {
// static branch // static branch
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout); ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
} }
}; };
} // end Intern } // end Intern
} // end Assimp } // end Assimp
#endif //!! AI_BYTESWAPPER_H_INC #endif //!! AI_BYTESWAPPER_H_INC

View File

@ -1,160 +1,160 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file aiFileIO -> IOSystem wrapper*/ /** @file aiFileIO -> IOSystem wrapper*/
#ifndef AI_CIOSYSTEM_H_INCLUDED #ifndef AI_CIOSYSTEM_H_INCLUDED
#define AI_CIOSYSTEM_H_INCLUDED #define AI_CIOSYSTEM_H_INCLUDED
#include "../include/assimp/cfileio.h" #include "../include/assimp/cfileio.h"
#include "../include/assimp/IOStream.hpp" #include "../include/assimp/IOStream.hpp"
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream class CIOStreamWrapper : public IOStream
{ {
friend class CIOSystemWrapper; friend class CIOSystemWrapper;
public: public:
CIOStreamWrapper(aiFile* pFile) CIOStreamWrapper(aiFile* pFile)
: mFile(pFile) : mFile(pFile)
{} {}
// ................................................................... // ...................................................................
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount
){ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
} }
// ................................................................... // ...................................................................
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount
){ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
} }
// ................................................................... // ...................................................................
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset,
aiOrigin pOrigin aiOrigin pOrigin
){ ){
return mFile->SeekProc(mFile,pOffset,pOrigin); return mFile->SeekProc(mFile,pOffset,pOrigin);
} }
// ................................................................... // ...................................................................
size_t Tell(void) const { size_t Tell(void) const {
return mFile->TellProc(mFile); return mFile->TellProc(mFile);
} }
// ................................................................... // ...................................................................
size_t FileSize() const { size_t FileSize() const {
return mFile->FileSizeProc(mFile); return mFile->FileSizeProc(mFile);
} }
// ................................................................... // ...................................................................
void Flush () { void Flush () {
return mFile->FlushProc(mFile); return mFile->FlushProc(mFile);
} }
private: private:
aiFile* mFile; aiFile* mFile;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOSystemWrapper : public IOSystem class CIOSystemWrapper : public IOSystem
{ {
public: public:
CIOSystemWrapper(aiFileIO* pFile) CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile) : mFileSystem(pFile)
{} {}
// ................................................................... // ...................................................................
bool Exists( const char* pFile) const { bool Exists( const char* pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
if (p){ if (p){
mFileSystem->CloseProc(mFileSystem,p); mFileSystem->CloseProc(mFileSystem,p);
return true; return true;
} }
return false; return false;
} }
// ................................................................... // ...................................................................
char getOsSeparator() const { char getOsSeparator() const {
#ifndef _WIN32 #ifndef _WIN32
return '/'; return '/';
#else #else
return '\\'; return '\\';
#endif #endif
} }
// ................................................................... // ...................................................................
IOStream* Open(const char* pFile,const char* pMode = "rb") { IOStream* Open(const char* pFile,const char* pMode = "rb") {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
if (!p) { if (!p) {
return NULL; return NULL;
} }
return new CIOStreamWrapper(p); return new CIOStreamWrapper(p);
} }
// ................................................................... // ...................................................................
void Close( IOStream* pFile) { void Close( IOStream* pFile) {
if (!pFile) { if (!pFile) {
return; return;
} }
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile); mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
delete pFile; delete pFile;
} }
private: private:
aiFileIO* mFileSystem; aiFileIO* mFileSystem;
}; };
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +1,174 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file COBLoader.h /** @file COBLoader.h
* @brief Declaration of the TrueSpace (*.cob,*.scn) importer class. * @brief Declaration of the TrueSpace (*.cob,*.scn) importer class.
*/ */
#ifndef INCLUDED_AI_COB_LOADER_H #ifndef INCLUDED_AI_COB_LOADER_H
#define INCLUDED_AI_COB_LOADER_H #define INCLUDED_AI_COB_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
#include "StreamReader.h" #include "StreamReader.h"
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
class LineSplitter; class LineSplitter;
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
// COBScene.h // COBScene.h
namespace COB { namespace COB {
struct ChunkInfo; struct ChunkInfo;
struct Node; struct Node;
struct Scene; struct Scene;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Importer class to load TrueSpace files (cob,scn) up to v6. /** Importer class to load TrueSpace files (cob,scn) up to v6.
* *
* Currently relatively limited, loads only ASCII files and needs more test coverage. */ * Currently relatively limited, loads only ASCII files and needs more test coverage. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter class COBImporter : public BaseImporter
{ {
public: public:
COBImporter(); COBImporter();
~COBImporter(); ~COBImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/ /** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file /** @brief Read from an ascii scene/object file
* @param out Receives output data. * @param out Receives output data.
* @param stream Stream to read from. */ * @param stream Stream to read from. */
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream); void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Read from a binary scene/object file /** @brief Read from a binary scene/object file
* @param out Receives output data. * @param out Receives output data.
* @param stream Stream to read from. */ * @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream); void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
private: private:
// Conversion to Assimp output format // Conversion to Assimp output format
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill); aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
private: private:
// ASCII file support // ASCII file support
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter); void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in); template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); 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 ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadMat1_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 ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadBone_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 ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadLght_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 ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadChan_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 // ASCII file logging stuff to add proper line numbers to messages
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message); static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogError_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 LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogDebug_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 LogWarn_Ascii (const Formatter::format& message);
static void LogError_Ascii (const Formatter::format& message); static void LogError_Ascii (const Formatter::format& message);
static void LogInfo_Ascii (const Formatter::format& message); static void LogInfo_Ascii (const Formatter::format& message);
static void LogDebug_Ascii (const Formatter::format& message); static void LogDebug_Ascii (const Formatter::format& message);
// Binary file support // Binary file support
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
void ReadString_Binary(std::string& out, StreamReaderLE& reader); void ReadString_Binary(std::string& out, StreamReaderLE& reader);
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo); 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 ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadBitM_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 ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadCame_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 ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadGrou_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); void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
}; // !class COBImporter }; // !class COBImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC #endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,274 +1,274 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file COBScene.h /** @file COBScene.h
* @brief Utilities for the COB importer. * @brief Utilities for the COB importer.
*/ */
#ifndef INCLUDED_AI_COB_SCENE_H #ifndef INCLUDED_AI_COB_SCENE_H
#define INCLUDED_AI_COB_SCENE_H #define INCLUDED_AI_COB_SCENE_H
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <deque> #include <deque>
#include "BaseImporter.h" #include "BaseImporter.h"
#include "./../include/assimp/material.h" #include "./../include/assimp/material.h"
namespace Assimp { namespace Assimp {
namespace COB { namespace COB {
// ------------------ // ------------------
/** Represents a single vertex index in a face */ /** Represents a single vertex index in a face */
struct VertexIndex struct VertexIndex
{ {
// intentionally uninitialized // intentionally uninitialized
unsigned int pos_idx,uv_idx; unsigned int pos_idx,uv_idx;
}; };
// ------------------ // ------------------
/** COB Face data structure */ /** COB Face data structure */
struct Face struct Face
{ {
// intentionally uninitialized // intentionally uninitialized
unsigned int material, flags; unsigned int material, flags;
std::vector<VertexIndex> indices; std::vector<VertexIndex> indices;
}; };
// ------------------ // ------------------
/** COB chunk header information */ /** COB chunk header information */
struct ChunkInfo struct ChunkInfo
{ {
enum {NO_SIZE=UINT_MAX}; enum {NO_SIZE=UINT_MAX};
ChunkInfo () ChunkInfo ()
: id (0) : id (0)
, parent_id (0) , parent_id (0)
, version (0) , version (0)
, size (NO_SIZE) , size (NO_SIZE)
{} {}
// Id of this chunk, unique within file // Id of this chunk, unique within file
unsigned int id; unsigned int id;
// and the corresponding parent // and the corresponding parent
unsigned int parent_id; unsigned int parent_id;
// version. v1.23 becomes 123 // version. v1.23 becomes 123
unsigned int version; unsigned int version;
// chunk size in bytes, only relevant for binary files // chunk size in bytes, only relevant for binary files
// NO_SIZE is also valid. // NO_SIZE is also valid.
unsigned int size; unsigned int size;
}; };
// ------------------ // ------------------
/** A node in the scenegraph */ /** A node in the scenegraph */
struct Node : public ChunkInfo struct Node : public ChunkInfo
{ {
enum Type { enum Type {
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
}; };
virtual ~Node() {} virtual ~Node() {}
Node(Type type) : type(type), unit_scale(1.f){} Node(Type type) : type(type), unit_scale(1.f){}
Type type; Type type;
// used during resolving // used during resolving
typedef std::deque<const Node*> ChildList; typedef std::deque<const Node*> ChildList;
mutable ChildList temp_children; mutable ChildList temp_children;
// unique name // unique name
std::string name; std::string name;
// local mesh transformation // local mesh transformation
aiMatrix4x4 transform; aiMatrix4x4 transform;
// scaling for this node to get to the metric system // scaling for this node to get to the metric system
float unit_scale; float unit_scale;
}; };
// ------------------ // ------------------
/** COB Mesh data structure */ /** COB Mesh data structure */
struct Mesh : public Node struct Mesh : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
enum DrawFlags { enum DrawFlags {
SOLID = 0x1, SOLID = 0x1,
TRANS = 0x2, TRANS = 0x2,
WIRED = 0x4, WIRED = 0x4,
BBOX = 0x8, BBOX = 0x8,
HIDE = 0x10 HIDE = 0x10
}; };
Mesh() Mesh()
: Node(TYPE_MESH) : Node(TYPE_MESH)
, draw_flags(SOLID) , draw_flags(SOLID)
{} {}
// vertex elements // vertex elements
std::vector<aiVector2D> texture_coords; std::vector<aiVector2D> texture_coords;
std::vector<aiVector3D> vertex_positions; std::vector<aiVector3D> vertex_positions;
// face data // face data
std::vector<Face> faces; std::vector<Face> faces;
// misc. drawing flags // misc. drawing flags
unsigned int draw_flags; unsigned int draw_flags;
// used during resolving // used during resolving
typedef std::deque<Face*> FaceRefList; typedef std::deque<Face*> FaceRefList;
typedef std::map< unsigned int,FaceRefList > TempMap; typedef std::map< unsigned int,FaceRefList > TempMap;
TempMap temp_map; TempMap temp_map;
}; };
// ------------------ // ------------------
/** COB Group data structure */ /** COB Group data structure */
struct Group : public Node struct Group : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Group() : Node(TYPE_GROUP) {} Group() : Node(TYPE_GROUP) {}
}; };
// ------------------ // ------------------
/** COB Bone data structure */ /** COB Bone data structure */
struct Bone : public Node struct Bone : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Bone() : Node(TYPE_BONE) {} Bone() : Node(TYPE_BONE) {}
}; };
// ------------------ // ------------------
/** COB Light data structure */ /** COB Light data structure */
struct Light : public Node struct Light : public Node
{ {
enum LightType { enum LightType {
SPOT,LOCAL,INFINITE SPOT,LOCAL,INFINITE
}; };
using ChunkInfo::operator=; using ChunkInfo::operator=;
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {} Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
aiColor3D color; aiColor3D color;
float angle,inner_angle; float angle,inner_angle;
LightType ltype; LightType ltype;
}; };
// ------------------ // ------------------
/** COB Camera data structure */ /** COB Camera data structure */
struct Camera : public Node struct Camera : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Camera() : Node(TYPE_CAMERA) {} Camera() : Node(TYPE_CAMERA) {}
}; };
// ------------------ // ------------------
/** COB Texture data structure */ /** COB Texture data structure */
struct Texture struct Texture
{ {
std::string path; std::string path;
aiUVTransform transform; aiUVTransform transform;
}; };
// ------------------ // ------------------
/** COB Material data structure */ /** COB Material data structure */
struct Material : ChunkInfo struct Material : ChunkInfo
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
enum Shader { enum Shader {
FLAT,PHONG,METAL FLAT,PHONG,METAL
}; };
enum AutoFacet { enum AutoFacet {
FACETED,AUTOFACETED,SMOOTH FACETED,AUTOFACETED,SMOOTH
}; };
Material() : alpha(),exp(),ior(),ka(),ks(1.f), Material() : alpha(),exp(),ior(),ka(),ks(1.f),
matnum(UINT_MAX), matnum(UINT_MAX),
shader(FLAT),autofacet(FACETED), shader(FLAT),autofacet(FACETED),
autofacet_angle() autofacet_angle()
{} {}
std::string type; std::string type;
aiColor3D rgb; aiColor3D rgb;
float alpha, exp, ior,ka,ks; float alpha, exp, ior,ka,ks;
unsigned int matnum; unsigned int matnum;
Shader shader; Shader shader;
AutoFacet autofacet; AutoFacet autofacet;
float autofacet_angle; float autofacet_angle;
boost::shared_ptr<Texture> tex_env,tex_bump,tex_color; boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
}; };
// ------------------ // ------------------
/** Embedded bitmap, for instance for the thumbnail image */ /** Embedded bitmap, for instance for the thumbnail image */
struct Bitmap : ChunkInfo struct Bitmap : ChunkInfo
{ {
Bitmap() : orig_size() {} Bitmap() : orig_size() {}
struct BitmapHeader struct BitmapHeader
{ {
}; };
BitmapHeader head; BitmapHeader head;
size_t orig_size; size_t orig_size;
std::vector<char> buff_zipped; std::vector<char> buff_zipped;
}; };
typedef std::deque< boost::shared_ptr<Node> > NodeList; typedef std::deque< boost::shared_ptr<Node> > NodeList;
typedef std::vector< Material > MaterialList; typedef std::vector< Material > MaterialList;
// ------------------ // ------------------
/** Represents a master COB scene, even if we loaded just a single COB file */ /** Represents a master COB scene, even if we loaded just a single COB file */
struct Scene struct Scene
{ {
NodeList nodes; NodeList nodes;
MaterialList materials; MaterialList materials;
// becomes *0 later // becomes *0 later
Bitmap thumbnail; Bitmap thumbnail;
}; };
} // end COB } // end COB
} // end Assimp } // end Assimp
#endif #endif

View File

@ -1,306 +1,306 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file CSMLoader.cpp /** @file CSMLoader.cpp
* Implementation of the CSM importer class. * Implementation of the CSM importer class.
*/ */
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
#include "CSMLoader.h" #include "CSMLoader.h"
#include "SkeletonMeshBuilder.h" #include "SkeletonMeshBuilder.h"
#include "ParsingUtils.h" #include "ParsingUtils.h"
#include "fast_atof.h" #include "fast_atof.h"
#include "../include/assimp/Importer.hpp" #include "../include/assimp/Importer.hpp"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
#include "../include/assimp/anim.h" #include "../include/assimp/anim.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"CharacterStudio Motion Importer (MoCap)", "CharacterStudio Motion Importer (MoCap)",
"", "",
"", "",
"", "",
aiImporterFlags_SupportTextFlavour, aiImporterFlags_SupportTextFlavour,
0, 0,
0, 0,
0, 0,
0, 0,
"csm" "csm"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CSMImporter::CSMImporter() CSMImporter::CSMImporter()
: noSkeletonMesh() : noSkeletonMesh()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
CSMImporter::~CSMImporter() CSMImporter::~CSMImporter()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{ {
// check file extension // check file extension
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if( extension == "csm") if( extension == "csm")
return true; return true;
if ((checkSig || !extension.length()) && pIOHandler) { if ((checkSig || !extension.length()) && pIOHandler) {
const char* tokens[] = {"$Filename"}; const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported // Build a string of all file extensions supported
const aiImporterDesc* CSMImporter::GetInfo () const const aiImporterDesc* CSMImporter::GetInfo () const
{ {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Setup configuration properties for the loader
void CSMImporter::SetupProperties(const Importer* pImp) void CSMImporter::SetupProperties(const Importer* pImp)
{ {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void CSMImporter::InternReadFile( const std::string& pFile, void CSMImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) { if( file.get() == NULL) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + "."); throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
} }
// allocate storage and copy the contents of the file to a memory buffer // allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2); TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0]; const char* buffer = &mBuffer2[0];
aiAnimation* anim = new aiAnimation(); aiAnimation* anim = new aiAnimation();
int first = 0, last = 0x00ffffff; int first = 0, last = 0x00ffffff;
// now process the file and look out for '$' sections // now process the file and look out for '$' sections
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if ('\0' == *buffer) if ('\0' == *buffer)
break; break;
if ('$' == *buffer) { if ('$' == *buffer) {
++buffer; ++buffer;
if (TokenMatchI(buffer,"firstframe",10)) { if (TokenMatchI(buffer,"firstframe",10)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
first = strtol10(buffer,&buffer); first = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"lastframe",9)) { else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
last = strtol10(buffer,&buffer); last = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"rate",4)) { else if (TokenMatchI(buffer,"rate",4)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
float d; float d;
buffer = fast_atoreal_move<float>(buffer,d); buffer = fast_atoreal_move<float>(buffer,d);
anim->mTicksPerSecond = d; anim->mTicksPerSecond = d;
} }
else if (TokenMatchI(buffer,"order",5)) { else if (TokenMatchI(buffer,"order",5)) {
std::vector< aiNodeAnim* > anims_temp; std::vector< aiNodeAnim* > anims_temp;
anims_temp.reserve(30); anims_temp.reserve(30);
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$') if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
break; // next section break; // next section
// Construct a new node animation channel and setup its name // Construct a new node animation channel and setup its name
anims_temp.push_back(new aiNodeAnim()); anims_temp.push_back(new aiNodeAnim());
aiNodeAnim* nda = anims_temp.back(); aiNodeAnim* nda = anims_temp.back();
char* ot = nda->mNodeName.data; char* ot = nda->mNodeName.data;
while (!IsSpaceOrNewLine(*buffer)) while (!IsSpaceOrNewLine(*buffer))
*ot++ = *buffer++; *ot++ = *buffer++;
*ot = '\0'; *ot = '\0';
nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data); nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
} }
anim->mNumChannels = anims_temp.size(); anim->mNumChannels = anims_temp.size();
if (!anim->mNumChannels) if (!anim->mNumChannels)
throw DeadlyImportError("CSM: Empty $order section"); throw DeadlyImportError("CSM: Empty $order section");
// copy over to the output animation // copy over to the output animation
anim->mChannels = new aiNodeAnim*[anim->mNumChannels]; anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels); ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
} }
else if (TokenMatchI(buffer,"points",6)) { else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels) if (!anim->mNumChannels)
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'"); 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 // If we know how many frames we'll read, we can preallocate some storage
unsigned int alloc = 100; unsigned int alloc = 100;
if (last != 0x00ffffff) if (last != 0x00ffffff)
{ {
alloc = last-first; alloc = last-first;
alloc += alloc>>2u; // + 25% alloc += alloc>>2u; // + 25%
for (unsigned int i = 0; i < anim->mNumChannels;++i) for (unsigned int i = 0; i < anim->mNumChannels;++i)
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc]; anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
} }
unsigned int filled = 0; unsigned int filled = 0;
// Now read all point data. // Now read all point data.
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) { if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
break; // next section break; // next section
} }
// read frame // read frame
const int frame = ::strtoul10(buffer,&buffer); const int frame = ::strtoul10(buffer,&buffer);
last = std::max(frame,last); last = std::max(frame,last);
first = std::min(frame,last); first = std::min(frame,last);
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* s = anim->mChannels[i]; aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */ if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
aiVectorKey* old = s->mPositionKeys; aiVectorKey* old = s->mPositionKeys;
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2]; s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc); ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
delete[] old; delete[] old;
} }
// read x,y,z // read x,y,z
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
if (TokenMatchI(buffer, "DROPOUT", 7)) { if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible // seems this is invalid marker data; at least the doc says it's possible
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)"); DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
} }
else { else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys; aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
sub->mTime = (double)frame; sub->mTime = (double)frame;
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
++s->mNumPositionKeys; ++s->mNumPositionKeys;
} }
} }
// update allocation granularity // update allocation granularity
if (filled == alloc) if (filled == alloc)
alloc *= 2; alloc *= 2;
++filled; ++filled;
} }
// all channels must be complete in order to continue safely. // all channels must be complete in order to continue safely.
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
if (!anim->mChannels[i]->mNumPositionKeys) if (!anim->mChannels[i]->mNumPositionKeys)
throw DeadlyImportError("CSM: Invalid marker track"); throw DeadlyImportError("CSM: Invalid marker track");
} }
} }
} }
else { else {
// advance to the next line // advance to the next line
SkipLine(&buffer); SkipLine(&buffer);
} }
} }
// Setup a proper animation duration // Setup a proper animation duration
anim->mDuration = last - std::min( first, 0 ); anim->mDuration = last - std::min( first, 0 );
// build a dummy root node with the tiny markers as children // build a dummy root node with the tiny markers as children
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("$CSM_DummyRoot"); pScene->mRootNode->mName.Set("$CSM_DummyRoot");
pScene->mRootNode->mNumChildren = anim->mNumChannels; pScene->mRootNode->mNumChildren = anim->mNumChannels;
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels]; pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* na = anim->mChannels[i]; aiNodeAnim* na = anim->mChannels[i];
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode(); aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
nd->mName = anim->mChannels[i]->mNodeName; nd->mName = anim->mChannels[i]->mNodeName;
nd->mParent = pScene->mRootNode; nd->mParent = pScene->mRootNode;
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation); aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
} }
// Store the one and only animation in the scene // Store the one and only animation in the scene
pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1]; pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
pScene->mAnimations[0] = anim; pScene->mAnimations[0] = anim;
anim->mName.Set("$CSM_MasterAnim"); anim->mName.Set("$CSM_MasterAnim");
// mark the scene as incomplete and run SkeletonMeshBuilder on it // mark the scene as incomplete and run SkeletonMeshBuilder on it
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
if (!noSkeletonMesh) { if (!noSkeletonMesh) {
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true); SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
} }
} }
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER #endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER

View File

@ -1,91 +1,91 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file CSMLoader.h /** @file CSMLoader.h
* Declaration of the CharacterStudio Motion importer class. * Declaration of the CharacterStudio Motion importer class.
*/ */
#ifndef INCLUDED_AI_CSM_LOADER_H #ifndef INCLUDED_AI_CSM_LOADER_H
#define INCLUDED_AI_CSM_LOADER_H #define INCLUDED_AI_CSM_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Importer class to load MOCAPs in CharacterStudio Motion format. /** Importer class to load MOCAPs in CharacterStudio Motion format.
* *
* A very rudimentary loader for the moment. No support for the hierarchy, * A very rudimentary loader for the moment. No support for the hierarchy,
* every marker is returned as child of root. * every marker is returned as child of root.
* *
* Link to file format specification: * Link to file format specification:
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf * <max_8_dvd>\samples\Motion\Docs\CSM.rtf
*/ */
class CSMImporter : public BaseImporter class CSMImporter : public BaseImporter
{ {
public: public:
CSMImporter(); CSMImporter();
~CSMImporter(); ~CSMImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
bool noSkeletonMesh; bool noSkeletonMesh;
}; // end of class CSMImporter }; // end of class CSMImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #endif // AI_AC3DIMPORTER_H_INC

View File

@ -1,317 +1,317 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the post processing step to calculate /** @file Implementation of the post processing step to calculate
* tangents and bitangents for all imported meshes * tangents and bitangents for all imported meshes
*/ */
// internal headers // internal headers
#include "CalcTangentsProcess.h" #include "CalcTangentsProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "TinyFormatter.h" #include "TinyFormatter.h"
#include "qnan.h" #include "qnan.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CalcTangentsProcess::CalcTangentsProcess() CalcTangentsProcess::CalcTangentsProcess()
: configMaxAngle( AI_DEG_TO_RAD(45.f) ) : configMaxAngle( AI_DEG_TO_RAD(45.f) )
, configSourceUV( 0 ) { , configSourceUV( 0 ) {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
CalcTangentsProcess::~CalcTangentsProcess() CalcTangentsProcess::~CalcTangentsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool CalcTangentsProcess::IsActive( unsigned int pFlags) const bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_CalcTangentSpace) != 0; return (pFlags & aiProcess_CalcTangentSpace) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void CalcTangentsProcess::SetupProperties(const Importer* pImp) void CalcTangentsProcess::SetupProperties(const Importer* pImp)
{ {
ai_assert( NULL != pImp ); ai_assert( NULL != pImp );
// get the current value of the property // get the current value of the property
configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f); configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f); configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f);
configMaxAngle = AI_DEG_TO_RAD(configMaxAngle); configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0); configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void CalcTangentsProcess::Execute( aiScene* pScene) void CalcTangentsProcess::Execute( aiScene* pScene)
{ {
ai_assert( NULL != pScene ); ai_assert( NULL != pScene );
DefaultLogger::get()->debug("CalcTangentsProcess begin"); DefaultLogger::get()->debug("CalcTangentsProcess begin");
bool bHas = false; bool bHas = false;
for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) { for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
} }
if ( bHas ) { if ( bHas ) {
DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated"); DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
} else { } else {
DefaultLogger::get()->debug("CalcTangentsProcess finished"); DefaultLogger::get()->debug("CalcTangentsProcess finished");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Calculates tangents and bitangents for the given mesh // Calculates tangents and bitangents for the given mesh
bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) 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 // 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 // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
// assert() it here. // assert() it here.
// assert( must be verbose, dammit); // assert( must be verbose, dammit);
if (pMesh->mTangents) // this implies that mBitangents is also there if (pMesh->mTangents) // this implies that mBitangents is also there
return false; return false;
// If the mesh consists of lines and/or points but not of // If the mesh consists of lines and/or points but not of
// triangles or higher-order polygons the normal vectors // triangles or higher-order polygons the normal vectors
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
{ {
DefaultLogger::get()->info("Tangents are undefined for line and point meshes"); DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
return false; return false;
} }
// what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
if( pMesh->mNormals == NULL) if( pMesh->mNormals == NULL)
{ {
DefaultLogger::get()->error("Failed to compute tangents; need normals"); DefaultLogger::get()->error("Failed to compute tangents; need normals");
return false; return false;
} }
if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] ) if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
{ {
DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV)); DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
return false; return false;
} }
const float angleEpsilon = 0.9999f; const float angleEpsilon = 0.9999f;
std::vector<bool> vertexDone( pMesh->mNumVertices, false); std::vector<bool> vertexDone( pMesh->mNumVertices, false);
const float qnan = get_qnan(); const float qnan = get_qnan();
// create space for the tangents and bitangents // create space for the tangents and bitangents
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices]; pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices]; pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
const aiVector3D* meshPos = pMesh->mVertices; const aiVector3D* meshPos = pMesh->mVertices;
const aiVector3D* meshNorm = pMesh->mNormals; const aiVector3D* meshNorm = pMesh->mNormals;
const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV]; const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV];
aiVector3D* meshTang = pMesh->mTangents; aiVector3D* meshTang = pMesh->mTangents;
aiVector3D* meshBitang = pMesh->mBitangents; aiVector3D* meshBitang = pMesh->mBitangents;
// calculate the tangent and bitangent for every face // calculate the tangent and bitangent for every face
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{ {
const aiFace& face = pMesh->mFaces[a]; const aiFace& face = pMesh->mFaces[a];
if (face.mNumIndices < 3) if (face.mNumIndices < 3)
{ {
// There are less than three indices, thus the tangent vector // There are less than three indices, thus the tangent vector
// is not defined. We are finished with these vertices now, // is not defined. We are finished with these vertices now,
// their tangent vectors are set to qnan. // their tangent vectors are set to qnan.
for (unsigned int i = 0; i < face.mNumIndices;++i) for (unsigned int i = 0; i < face.mNumIndices;++i)
{ {
unsigned int idx = face.mIndices[i]; unsigned int idx = face.mIndices[i];
vertexDone [idx] = true; vertexDone [idx] = true;
meshTang [idx] = aiVector3D(qnan); meshTang [idx] = aiVector3D(qnan);
meshBitang [idx] = aiVector3D(qnan); meshBitang [idx] = aiVector3D(qnan);
} }
continue; continue;
} }
// triangle or polygon... we always use only the first three indices. A polygon // triangle or polygon... we always use only the first three indices. A polygon
// is supposed to be planar anyways.... // is supposed to be planar anyways....
// FIXME: (thom) create correct calculation for multi-vertex polygons maybe? // 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]; const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
// position differences p1->p2 and p1->p3 // position differences p1->p2 and p1->p3
aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0]; aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
// texture offset p1->p2 and p1->p3 // texture offset p1->p2 and p1->p3
float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y; 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 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; float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
// when t1, t2, t3 in same position in UV space, just use default UV direction. // when t1, t2, t3 in same position in UV space, just use default UV direction.
if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) { if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) {
sx = 0.0; sy = 1.0; sx = 0.0; sy = 1.0;
tx = 1.0; ty = 0.0; tx = 1.0; ty = 0.0;
} }
// tangent points in the direction where to positive X axis of the texture coord's would point in model space // tangent points in the direction where to positive X axis of the texture coord's would point in model space
// bitangent's points along the positive Y axis of the texture coord's, respectively // bitangent's points along the positive Y axis of the texture coord's, respectively
aiVector3D tangent, bitangent; aiVector3D tangent, bitangent;
tangent.x = (w.x * sy - v.x * ty) * dirCorrection; tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
tangent.y = (w.y * sy - v.y * ty) * dirCorrection; tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
tangent.z = (w.z * sy - v.z * ty) * dirCorrection; tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection; bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection; bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection; bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
// store for every vertex of that face // store for every vertex of that face
for( unsigned int b = 0; b < face.mNumIndices; ++b ) { for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
unsigned int p = face.mIndices[b]; unsigned int p = face.mIndices[b];
// project tangent and bitangent into the plane formed by the vertex' normal // project tangent and bitangent into the plane formed by the vertex' normal
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]); aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
localTangent.Normalize(); localBitangent.Normalize(); localTangent.Normalize(); localBitangent.Normalize();
// reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN. // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z); bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z); bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z);
if (invalid_tangent != invalid_bitangent) { if (invalid_tangent != invalid_bitangent) {
if (invalid_tangent) { if (invalid_tangent) {
localTangent = meshNorm[p] ^ localBitangent; localTangent = meshNorm[p] ^ localBitangent;
localTangent.Normalize(); localTangent.Normalize();
} else { } else {
localBitangent = localTangent ^ meshNorm[p]; localBitangent = localTangent ^ meshNorm[p];
localBitangent.Normalize(); localBitangent.Normalize();
} }
} }
// and write it into the mesh. // and write it into the mesh.
meshTang[ p ] = localTangent; meshTang[ p ] = localTangent;
meshBitang[ p ] = localBitangent; meshBitang[ p ] = localBitangent;
} }
} }
// create a helper to quickly find locally close vertices among the vertex array // 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 // FIX: check whether we can reuse the SpatialSort of a previous step
SpatialSort* vertexFinder = NULL; SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder; SpatialSort _vertexFinder;
float posEpsilon; float posEpsilon;
if (shared) if (shared)
{ {
std::vector<std::pair<SpatialSort,float> >* avf; std::vector<std::pair<SpatialSort,float> >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf); shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf) if (avf)
{ {
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex); std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
vertexFinder = &blubb.first; vertexFinder = &blubb.first;
posEpsilon = blubb.second;; posEpsilon = blubb.second;;
} }
} }
if (!vertexFinder) if (!vertexFinder)
{ {
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder; vertexFinder = &_vertexFinder;
posEpsilon = ComputePositionEpsilon(pMesh); posEpsilon = ComputePositionEpsilon(pMesh);
} }
std::vector<unsigned int> verticesFound; std::vector<unsigned int> verticesFound;
const float fLimit = cosf(configMaxAngle); const float fLimit = cosf(configMaxAngle);
std::vector<unsigned int> closeVertices; std::vector<unsigned int> closeVertices;
// in the second pass we now smooth out all tangents and bitangents at the same local position // in the second pass we now smooth out all tangents and bitangents at the same local position
// if they are not too far off. // if they are not too far off.
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
{ {
if( vertexDone[a]) if( vertexDone[a])
continue; continue;
const aiVector3D& origPos = pMesh->mVertices[a]; const aiVector3D& origPos = pMesh->mVertices[a];
const aiVector3D& origNorm = pMesh->mNormals[a]; const aiVector3D& origNorm = pMesh->mNormals[a];
const aiVector3D& origTang = pMesh->mTangents[a]; const aiVector3D& origTang = pMesh->mTangents[a];
const aiVector3D& origBitang = pMesh->mBitangents[a]; const aiVector3D& origBitang = pMesh->mBitangents[a];
closeVertices.resize( 0 ); closeVertices.resize( 0 );
// find all vertices close to that position // find all vertices close to that position
vertexFinder->FindPositions( origPos, posEpsilon, verticesFound); vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
closeVertices.reserve (verticesFound.size()+5); closeVertices.reserve (verticesFound.size()+5);
closeVertices.push_back( a); closeVertices.push_back( a);
// look among them for other vertices sharing the same normal and a close-enough tangent/bitangent // 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++) for( unsigned int b = 0; b < verticesFound.size(); b++)
{ {
unsigned int idx = verticesFound[b]; unsigned int idx = verticesFound[b];
if( vertexDone[idx]) if( vertexDone[idx])
continue; continue;
if( meshNorm[idx] * origNorm < angleEpsilon) if( meshNorm[idx] * origNorm < angleEpsilon)
continue; continue;
if( meshTang[idx] * origTang < fLimit) if( meshTang[idx] * origTang < fLimit)
continue; continue;
if( meshBitang[idx] * origBitang < fLimit) if( meshBitang[idx] * origBitang < fLimit)
continue; continue;
// it's similar enough -> add it to the smoothing group // it's similar enough -> add it to the smoothing group
closeVertices.push_back( idx); closeVertices.push_back( idx);
vertexDone[idx] = true; vertexDone[idx] = true;
} }
// smooth the tangents and bitangents of all vertices that were found to be close enough // smooth the tangents and bitangents of all vertices that were found to be close enough
aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0); aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
for( unsigned int b = 0; b < closeVertices.size(); ++b) for( unsigned int b = 0; b < closeVertices.size(); ++b)
{ {
smoothTangent += meshTang[ closeVertices[b] ]; smoothTangent += meshTang[ closeVertices[b] ];
smoothBitangent += meshBitang[ closeVertices[b] ]; smoothBitangent += meshBitang[ closeVertices[b] ];
} }
smoothTangent.Normalize(); smoothTangent.Normalize();
smoothBitangent.Normalize(); smoothBitangent.Normalize();
// and write it back into all affected tangents // and write it back into all affected tangents
for( unsigned int b = 0; b < closeVertices.size(); ++b) for( unsigned int b = 0; b < closeVertices.size(); ++b)
{ {
meshTang[ closeVertices[b] ] = smoothTangent; meshTang[ closeVertices[b] ] = smoothTangent;
meshBitang[ closeVertices[b] ] = smoothBitangent; meshBitang[ closeVertices[b] ] = smoothBitangent;
} }
} }
return true; return true;
} }

View File

@ -1,115 +1,115 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to calculate tangents and /** @file Defines a post processing step to calculate tangents and
bitangents on all imported meshes.*/ bitangents on all imported meshes.*/
#ifndef AI_CALCTANGENTSPROCESS_H_INC #ifndef AI_CALCTANGENTSPROCESS_H_INC
#define AI_CALCTANGENTSPROCESS_H_INC #define AI_CALCTANGENTSPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
struct aiMesh; struct aiMesh;
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex /** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
* of all meshes. It is expected to be run before the JoinVerticesProcess runs * of all meshes. It is expected to be run before the JoinVerticesProcess runs
* because the joining of vertices also considers tangents and bitangents for * because the joining of vertices also considers tangents and bitangents for
* uniqueness. * uniqueness.
*/ */
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
{ {
public: public:
CalcTangentsProcess(); CalcTangentsProcess();
~CalcTangentsProcess(); ~CalcTangentsProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. * @param pFlags The processing flags the importer was called with.
* A bitwise combination of #aiPostProcessSteps. * A bitwise combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, * @return true if the process is present in this flag fields,
* false if not. * false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ExecuteOnScene(). /** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration * The function is a request to the process to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// setter for configMaxAngle // setter for configMaxAngle
inline void SetMaxSmoothAngle(float f) inline void SetMaxSmoothAngle(float f)
{ {
configMaxAngle =f; configMaxAngle =f;
} }
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Calculates tangents and bitangents for a specific mesh. /** Calculates tangents and bitangents for a specific mesh.
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
* @param meshIndex Index of the mesh * @param meshIndex Index of the mesh
*/ */
bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex); bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
private: private:
/** Configuration option: maximum smoothing angle, in radians*/ /** Configuration option: maximum smoothing angle, in radians*/
float configMaxAngle; float configMaxAngle;
unsigned int configSourceUV; unsigned int configSourceUV;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_CALCTANGENTSPROCESS_H_INC #endif // AI_CALCTANGENTSPROCESS_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +1,202 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ColladaExporter.h /** @file ColladaExporter.h
* Declares the exporter class to write a scene to a Collada file * Declares the exporter class to write a scene to a Collada file
*/ */
#ifndef AI_COLLADAEXPORTER_H_INC #ifndef AI_COLLADAEXPORTER_H_INC
#define AI_COLLADAEXPORTER_H_INC #define AI_COLLADAEXPORTER_H_INC
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include "../include/assimp/material.h" #include "../include/assimp/material.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/light.h" #include "../include/assimp/light.h"
#include "../include/assimp/Exporter.hpp" #include "../include/assimp/Exporter.hpp"
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <map> #include <map>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
struct aiScene; struct aiScene;
struct aiNode; struct aiNode;
namespace Assimp namespace Assimp
{ {
/// Helper class to export a given scene to a Collada file. Just for my personal /// Helper class to export a given scene to a Collada file. Just for my personal
/// comfort when implementing it. /// comfort when implementing it.
class ColladaExporter class ColladaExporter
{ {
public: public:
/// Constructor for a specific scene to export /// Constructor for a specific scene to export
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
/// Destructor /// Destructor
virtual ~ColladaExporter(); virtual ~ColladaExporter();
protected: protected:
/// Starts writing the contents /// Starts writing the contents
void WriteFile(); void WriteFile();
/// Writes the asset header /// Writes the asset header
void WriteHeader(); void WriteHeader();
/// Writes the embedded textures /// Writes the embedded textures
void WriteTextures(); void WriteTextures();
/// Writes the material setup /// Writes the material setup
void WriteMaterials(); void WriteMaterials();
/// Writes the cameras library /// Writes the cameras library
void WriteCamerasLibrary(); void WriteCamerasLibrary();
// Write a camera entry // Write a camera entry
void WriteCamera(size_t pIndex); void WriteCamera(size_t pIndex);
/// Writes the cameras library /// Writes the cameras library
void WriteLightsLibrary(); void WriteLightsLibrary();
// Write a camera entry // Write a camera entry
void WriteLight(size_t pIndex); void WriteLight(size_t pIndex);
void WritePointLight(const aiLight *const light); void WritePointLight(const aiLight *const light);
void WriteDirectionalLight(const aiLight *const light); void WriteDirectionalLight(const aiLight *const light);
void WriteSpotLight(const aiLight *const light); void WriteSpotLight(const aiLight *const light);
void WriteAmbienttLight(const aiLight *const light); void WriteAmbienttLight(const aiLight *const light);
/// Writes the geometry library /// Writes the geometry library
void WriteGeometryLibrary(); void WriteGeometryLibrary();
/// Writes the given mesh /// Writes the given mesh
void WriteGeometry( size_t pIndex); void WriteGeometry( size_t pIndex);
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color }; enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
/// Writes a float array of the given type /// Writes a float array of the given type
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount); void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
/// Writes the scene library /// Writes the scene library
void WriteSceneLibrary(); void WriteSceneLibrary();
/// Recursively writes the given node /// Recursively writes the given node
void WriteNode( aiNode* pNode); void WriteNode( aiNode* pNode);
/// Enters a new xml element, which increases the indentation /// Enters a new xml element, which increases the indentation
void PushTag() { startstr.append( " "); } void PushTag() { startstr.append( " "); }
/// Leaves an element, decreasing the indentation /// Leaves an element, decreasing the indentation
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); } void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
/// Creates a mesh ID for the given mesh /// Creates a mesh ID for the given mesh
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); } std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
public: public:
/// Stringstream to write all output into /// Stringstream to write all output into
std::stringstream mOutput; std::stringstream mOutput;
protected: protected:
/// The IOSystem for output /// The IOSystem for output
IOSystem* mIOSystem; IOSystem* mIOSystem;
/// Path of the directory where the scene will be exported /// Path of the directory where the scene will be exported
const std::string mPath; const std::string mPath;
/// Name of the file (without extension) where the scene will be exported /// Name of the file (without extension) where the scene will be exported
const std::string mFile; const std::string mFile;
/// The scene to be written /// The scene to be written
const aiScene* mScene; const aiScene* mScene;
bool mSceneOwned; bool mSceneOwned;
/// current line start string, contains the current indentation for simple stream insertion /// current line start string, contains the current indentation for simple stream insertion
std::string startstr; std::string startstr;
/// current line end string for simple stream insertion /// current line end string for simple stream insertion
std::string endstr; std::string endstr;
// pair of color and texture - texture precedences color // pair of color and texture - texture precedences color
struct Surface struct Surface
{ {
bool exist; bool exist;
aiColor4D color; aiColor4D color;
std::string texture; std::string texture;
size_t channel; size_t channel;
Surface() { exist = false; channel = 0; } Surface() { exist = false; channel = 0; }
}; };
struct Property struct Property
{ {
bool exist; bool exist;
float value; float value;
Property() Property()
: exist(false) : exist(false)
, value(0.0f) , value(0.0f)
{} {}
}; };
// summarize a material in an convinient way. // summarize a material in an convinient way.
struct Material struct Material
{ {
std::string name; std::string name;
std::string shading_model; std::string shading_model;
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal; Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction; Property shininess, transparency, index_refraction;
Material() {} Material() {}
}; };
std::vector<Material> materials; std::vector<Material> materials;
std::map<unsigned int, std::string> textures; std::map<unsigned int, std::string> textures;
protected: protected:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
/// Reads a single surface entry from the given material keys /// Reads a single surface entry from the given material keys
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex); void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
/// Writes an image entry for the given surface /// Writes an image entry for the given surface
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd); void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
/// Writes the two parameters necessary for referencing a texture in an effect entry /// Writes the two parameters necessary for referencing a texture in an effect entry
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName); void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
/// Writes a color-or-texture entry into an effect definition /// Writes a color-or-texture entry into an effect definition
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
/// Writes a scalar property /// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName); void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName);
}; };
} }
#endif // !! AI_COLLADAEXPORTER_H_INC #endif // !! AI_COLLADAEXPORTER_H_INC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +1,252 @@
/** Defines the collada loader class */ /** Defines the collada loader class */
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef AI_COLLADALOADER_H_INC #ifndef AI_COLLADALOADER_H_INC
#define AI_COLLADALOADER_H_INC #define AI_COLLADALOADER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
#include "ColladaParser.h" #include "ColladaParser.h"
struct aiNode; struct aiNode;
struct aiCamera; struct aiCamera;
struct aiLight; struct aiLight;
struct aiTexture; struct aiTexture;
struct aiAnimation; struct aiAnimation;
namespace Assimp namespace Assimp
{ {
struct ColladaMeshIndex struct ColladaMeshIndex
{ {
std::string mMeshID; std::string mMeshID;
size_t mSubMesh; size_t mSubMesh;
std::string mMaterial; std::string mMaterial;
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial) ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial) : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
{ } { }
bool operator < (const ColladaMeshIndex& p) const bool operator < (const ColladaMeshIndex& p) const
{ {
if( mMeshID == p.mMeshID) if( mMeshID == p.mMeshID)
{ {
if( mSubMesh == p.mSubMesh) if( mSubMesh == p.mSubMesh)
return mMaterial < p.mMaterial; return mMaterial < p.mMaterial;
else else
return mSubMesh < p.mSubMesh; return mSubMesh < p.mSubMesh;
} else } else
{ {
return mMeshID < p.mMeshID; return mMeshID < p.mMeshID;
} }
} }
}; };
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing /** 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. * more useless stuff, so I limited the data to what I think is useful for games.
*/ */
class ColladaLoader : public BaseImporter class ColladaLoader : public BaseImporter
{ {
public: public:
ColladaLoader(); ColladaLoader();
~ColladaLoader(); ~ColladaLoader();
public: public:
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
protected: protected:
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
/** Recursively constructs a scene node for the given parser node and returns it. */ /** Recursively constructs a scene node for the given parser node and returns it. */
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode); aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
/** Resolve node instances */ /** Resolve node instances */
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode, void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
std::vector<const Collada::Node*>& resolved); std::vector<const Collada::Node*>& resolved);
/** Builds meshes for the given node and references them */ /** Builds meshes for the given node and references them */
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ /** 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, aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace); const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
/** Builds cameras for the given node and references them */ /** Builds cameras for the given node and references them */
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Builds lights for the given node and references them */ /** Builds lights for the given node and references them */
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Stores all meshes in the given scene */ /** Stores all meshes in the given scene */
void StoreSceneMeshes( aiScene* pScene); void StoreSceneMeshes( aiScene* pScene);
/** Stores all materials in the given scene */ /** Stores all materials in the given scene */
void StoreSceneMaterials( aiScene* pScene); void StoreSceneMaterials( aiScene* pScene);
/** Stores all lights in the given scene */ /** Stores all lights in the given scene */
void StoreSceneLights( aiScene* pScene); void StoreSceneLights( aiScene* pScene);
/** Stores all cameras in the given scene */ /** Stores all cameras in the given scene */
void StoreSceneCameras( aiScene* pScene); void StoreSceneCameras( aiScene* pScene);
/** Stores all textures in the given scene */ /** Stores all textures in the given scene */
void StoreSceneTextures( aiScene* pScene); void StoreSceneTextures( aiScene* pScene);
/** Stores all animations /** Stores all animations
* @param pScene target scene to store the anims * @param pScene target scene to store the anims
*/ */
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser); void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
/** Stores all animations for the given source anim and its nested child animations /** Stores all animations for the given source anim and its nested child animations
* @param pScene target scene to store the anims * @param pScene target scene to store the anims
* @param pSrcAnim the source animation to process * @param pSrcAnim the source animation to process
* @param pPrefix Prefix to the name in case of nested animations * @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); void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
/** Constructs the animation for the given source anim */ /** Constructs the animation for the given source anim */
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName); void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
/** Constructs materials from the collada material definitions */ /** Constructs materials from the collada material definitions */
void BuildMaterials( ColladaParser& pParser, aiScene* pScene); void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
/** Fill materials from the collada material definitions */ /** Fill materials from the collada material definitions */
void FillMaterials( const ColladaParser& pParser, aiScene* pScene); void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
/** Resolve UV channel mappings*/ /** Resolve UV channel mappings*/
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler, void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
const Collada::SemanticMappingTable& table); const Collada::SemanticMappingTable& table);
/** Add a texture and all of its sampling properties to a material*/ /** Add a texture and all of its sampling properties to a material*/
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser, void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& effect, const Collada::Effect& effect,
const Collada::Sampler& sampler, const Collada::Sampler& sampler,
aiTextureType type, unsigned int idx = 0); aiTextureType type, unsigned int idx = 0);
/** Resolves the texture name for the given effect texture entry */ /** Resolves the texture name for the given effect texture entry */
aiString FindFilenameForEffectTexture( const ColladaParser& pParser, aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName); const Collada::Effect& pEffect, const std::string& pName);
/** Converts a path read from a collada file to the usual representation */ /** Converts a path read from a collada file to the usual representation */
void ConvertPath( aiString& ss); void ConvertPath( aiString& ss);
/** Reads a float value from an accessor and its data array. /** Reads a float value from an accessor and its data array.
* @param pAccessor The accessor to use for reading * @param pAccessor The accessor to use for reading
* @param pData The data array to read from * @param pData The data array to read from
* @param pIndex The index of the element to retrieve * @param pIndex The index of the element to retrieve
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
* @return the specified value * @return the specified value
*/ */
float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const; 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. /** Reads a string value from an accessor and its data array.
* @param pAccessor The accessor to use for reading * @param pAccessor The accessor to use for reading
* @param pData The data array to read from * @param pData The data array to read from
* @param pIndex The index of the element to retrieve * @param pIndex The index of the element to retrieve
* @return the specified value * @return the specified value
*/ */
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const; const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
/** Recursively collects all nodes into the given array */ /** Recursively collects all nodes into the given array */
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const; void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
/** Finds a node in the collada scene by the given name */ /** Finds a node in the collada scene by the given name */
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const; const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
/** Finds a node in the collada scene by the given SID */ /** Finds a node in the collada scene by the given SID */
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const; 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 */ /** Finds a proper name for a node derived from the collada-node's properties */
std::string FindNameForNode( const Collada::Node* pNode); std::string FindNameForNode( const Collada::Node* pNode);
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** Which mesh-material compound was stored under which mesh ID */ /** Which mesh-material compound was stored under which mesh ID */
std::map<ColladaMeshIndex, size_t> mMeshIndexByID; std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
/** Which material was stored under which index in the scene */ /** Which material was stored under which index in the scene */
std::map<std::string, size_t> mMaterialIndexByName; std::map<std::string, size_t> mMaterialIndexByName;
/** Accumulated meshes for the target scene */ /** Accumulated meshes for the target scene */
std::vector<aiMesh*> mMeshes; std::vector<aiMesh*> mMeshes;
/** Temporary material list */ /** Temporary material list */
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats; std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
/** Temporary camera list */ /** Temporary camera list */
std::vector<aiCamera*> mCameras; std::vector<aiCamera*> mCameras;
/** Temporary light list */ /** Temporary light list */
std::vector<aiLight*> mLights; std::vector<aiLight*> mLights;
/** Temporary texture list */ /** Temporary texture list */
std::vector<aiTexture*> mTextures; std::vector<aiTexture*> mTextures;
/** Accumulated animations for the target scene */ /** Accumulated animations for the target scene */
std::vector<aiAnimation*> mAnims; std::vector<aiAnimation*> mAnims;
bool noSkeletonMesh; bool noSkeletonMesh;
bool ignoreUpDirection; bool ignoreUpDirection;
bool invertTransparency; bool invertTransparency;
/** Used by FindNameForNode() to generate unique node names */ /** Used by FindNameForNode() to generate unique node names */
unsigned int mNodeNameCounter; unsigned int mNodeNameCounter;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COLLADALOADER_H_INC #endif // AI_COLLADALOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,352 +1,352 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ColladaParser.h /** @file ColladaParser.h
* @brief Defines the parser helper class for the collada loader * @brief Defines the parser helper class for the collada loader
*/ */
#ifndef AI_COLLADAPARSER_H_INC #ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC #define AI_COLLADAPARSER_H_INC
#include "irrXMLWrapper.h" #include "irrXMLWrapper.h"
#include "ColladaHelper.h" #include "ColladaHelper.h"
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <boost/format.hpp> #include <boost/format.hpp>
namespace Assimp namespace Assimp
{ {
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/** Parser helper class for the Collada loader. /** Parser helper class for the Collada loader.
* *
* Does all the XML reading and builds internal data structures from it, * Does all the XML reading and builds internal data structures from it,
* but leaves the resolving of all the references to the loader. * but leaves the resolving of all the references to the loader.
*/ */
class ColladaParser class ColladaParser
{ {
friend class ColladaLoader; friend class ColladaLoader;
protected: protected:
/** Constructor from XML file */ /** Constructor from XML file */
ColladaParser( IOSystem* pIOHandler, const std::string& pFile); ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
/** Destructor */ /** Destructor */
~ColladaParser(); ~ColladaParser();
/** Reads the contents of the file */ /** Reads the contents of the file */
void ReadContents(); void ReadContents();
/** Reads the structure of the file */ /** Reads the structure of the file */
void ReadStructure(); void ReadStructure();
/** Reads asset informations such as coordinate system informations and legal blah */ /** Reads asset informations such as coordinate system informations and legal blah */
void ReadAssetInfo(); void ReadAssetInfo();
/** Reads the animation library */ /** Reads the animation library */
void ReadAnimationLibrary(); void ReadAnimationLibrary();
/** Reads an animation into the given parent structure */ /** Reads an animation into the given parent structure */
void ReadAnimation( Collada::Animation* pParent); void ReadAnimation( Collada::Animation* pParent);
/** Reads an animation sampler into the given anim channel */ /** Reads an animation sampler into the given anim channel */
void ReadAnimationSampler( Collada::AnimationChannel& pChannel); void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
/** Reads the skeleton controller library */ /** Reads the skeleton controller library */
void ReadControllerLibrary(); void ReadControllerLibrary();
/** Reads a controller into the given mesh structure */ /** Reads a controller into the given mesh structure */
void ReadController( Collada::Controller& pController); void ReadController( Collada::Controller& pController);
/** Reads the joint definitions for the given controller */ /** Reads the joint definitions for the given controller */
void ReadControllerJoints( Collada::Controller& pController); void ReadControllerJoints( Collada::Controller& pController);
/** Reads the joint weights for the given controller */ /** Reads the joint weights for the given controller */
void ReadControllerWeights( Collada::Controller& pController); void ReadControllerWeights( Collada::Controller& pController);
/** Reads the image library contents */ /** Reads the image library contents */
void ReadImageLibrary(); void ReadImageLibrary();
/** Reads an image entry into the given image */ /** Reads an image entry into the given image */
void ReadImage( Collada::Image& pImage); void ReadImage( Collada::Image& pImage);
/** Reads the material library */ /** Reads the material library */
void ReadMaterialLibrary(); void ReadMaterialLibrary();
/** Reads a material entry into the given material */ /** Reads a material entry into the given material */
void ReadMaterial( Collada::Material& pMaterial); void ReadMaterial( Collada::Material& pMaterial);
/** Reads the camera library */ /** Reads the camera library */
void ReadCameraLibrary(); void ReadCameraLibrary();
/** Reads a camera entry into the given camera */ /** Reads a camera entry into the given camera */
void ReadCamera( Collada::Camera& pCamera); void ReadCamera( Collada::Camera& pCamera);
/** Reads the light library */ /** Reads the light library */
void ReadLightLibrary(); void ReadLightLibrary();
/** Reads a light entry into the given light */ /** Reads a light entry into the given light */
void ReadLight( Collada::Light& pLight); void ReadLight( Collada::Light& pLight);
/** Reads the effect library */ /** Reads the effect library */
void ReadEffectLibrary(); void ReadEffectLibrary();
/** Reads an effect entry into the given effect*/ /** Reads an effect entry into the given effect*/
void ReadEffect( Collada::Effect& pEffect); void ReadEffect( Collada::Effect& pEffect);
/** Reads an COMMON effect profile */ /** Reads an COMMON effect profile */
void ReadEffectProfileCommon( Collada::Effect& pEffect); void ReadEffectProfileCommon( Collada::Effect& pEffect);
/** Read sampler properties */ /** Read sampler properties */
void ReadSamplerProperties( Collada::Sampler& pSampler); void ReadSamplerProperties( Collada::Sampler& pSampler);
/** Reads an effect entry containing a color or a texture defining that color */ /** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler); void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
/** Reads an effect entry containing a float */ /** Reads an effect entry containing a float */
void ReadEffectFloat( float& pFloat); void ReadEffectFloat( float& pFloat);
/** Reads an effect parameter specification of any kind */ /** Reads an effect parameter specification of any kind */
void ReadEffectParam( Collada::EffectParam& pParam); void ReadEffectParam( Collada::EffectParam& pParam);
/** Reads the geometry library contents */ /** Reads the geometry library contents */
void ReadGeometryLibrary(); void ReadGeometryLibrary();
/** Reads a geometry from the geometry library. */ /** Reads a geometry from the geometry library. */
void ReadGeometry( Collada::Mesh* pMesh); void ReadGeometry( Collada::Mesh* pMesh);
/** Reads a mesh from the geometry library */ /** Reads a mesh from the geometry library */
void ReadMesh( Collada::Mesh* pMesh); void ReadMesh( Collada::Mesh* pMesh);
/** Reads a source element - a combination of raw data and an accessor defining /** Reads a source element - a combination of raw data and an accessor defining
* things that should not be redefinable. Yes, that's another rant. * things that should not be redefinable. Yes, that's another rant.
*/ */
void ReadSource(); void ReadSource();
/** Reads a data array holding a number of elements, and stores it in the global library. /** 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. * Currently supported are array of floats and arrays of strings.
*/ */
void ReadDataArray(); void ReadDataArray();
/** Reads an accessor and stores it in the global library under the given ID - /** Reads an accessor and stores it in the global library under the given ID -
* accessors use the ID of the parent <source> element * accessors use the ID of the parent <source> element
*/ */
void ReadAccessor( const std::string& pID); void ReadAccessor( const std::string& pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */ /** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData( Collada::Mesh* pMesh); void ReadVertexData( Collada::Mesh* pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */ /** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData( Collada::Mesh* pMesh); void ReadIndexData( Collada::Mesh* pMesh);
/** Reads a single input channel element and stores it in the given array, if valid */ /** Reads a single input channel element and stores it in the given array, if valid */
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels); void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */ /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType); size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
/** Copies the data for a single primitive into the mesh, based on the InputChannels */ /** Copies the data for a single primitive into the mesh, based on the InputChannels */
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t>& indices); size_t currentPrimitive, const std::vector<size_t>& indices);
/** Reads one triangle of a tristrip into the mesh */ /** Reads one triangle of a tristrip into the mesh */
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh, void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices); std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */ /** 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); void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
/** Reads the library of node hierarchies and scene parts */ /** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary(); void ReadSceneLibrary();
/** Reads a scene node's contents including children and stores it in the given node */ /** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode( Collada::Node* pNode); void ReadSceneNode( Collada::Node* pNode);
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ /** 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); void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
/** Reads a mesh reference in a node and adds it to the node's mesh list */ /** Reads a mesh reference in a node and adds it to the node's mesh list */
void ReadNodeGeometry( Collada::Node* pNode); void ReadNodeGeometry( Collada::Node* pNode);
/** Reads the collada scene */ /** Reads the collada scene */
void ReadScene(); void ReadScene();
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl); void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
protected: protected:
/** Aborts the file reading with an exception */ /** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
/** Skips all data until the end node of the current element */ /** Skips all data until the end node of the current element */
void SkipElement(); void SkipElement();
/** Skips all data until the end node of the given element */ /** Skips all data until the end node of the given element */
void SkipElement( const char* pElement); void SkipElement( const char* pElement);
/** Compares the current xml element name to the given string and returns true if equal */ /** Compares the current xml element name to the given string and returns true if equal */
bool IsElement( const char* pName) const; bool IsElement( const char* pName) const;
/** Tests for the opening tag of the given element, throws an exception if not found */ /** Tests for the opening tag of the given element, throws an exception if not found */
void TestOpening( const char* pName); void TestOpening( const char* pName);
/** Tests for the closing tag of the given element, throws an exception if not found */ /** Tests for the closing tag of the given element, throws an exception if not found */
void TestClosing( const char* pName); void TestClosing( const char* pName);
/** Checks the present element for the presence of the attribute, returns its index /** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */ or throws an exception if not found */
int GetAttribute( const char* pAttr) const; int GetAttribute( const char* pAttr) const;
/** Returns the index of the named attribute or -1 if not found. Does not throw, /** Returns the index of the named attribute or -1 if not found. Does not throw,
therefore useful for optional attributes */ therefore useful for optional attributes */
int TestAttribute( const char* pAttr) const; int TestAttribute( const char* pAttr) const;
/** Reads the text contents of an element, throws an exception if not given. /** Reads the text contents of an element, throws an exception if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* GetTextContent(); const char* GetTextContent();
/** Reads the text contents of an element, returns NULL if not given. /** Reads the text contents of an element, returns NULL if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* TestTextContent(); const char* TestTextContent();
/** Reads a single bool from current text content */ /** Reads a single bool from current text content */
bool ReadBoolFromTextContent(); bool ReadBoolFromTextContent();
/** Reads a single float from current text content */ /** Reads a single float from current text content */
float ReadFloatFromTextContent(); float ReadFloatFromTextContent();
/** Calculates the resulting transformation from all the given transform steps */ /** Calculates the resulting transformation from all the given transform steps */
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const; aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
/** Determines the input data type for the given semantic string */ /** Determines the input data type for the given semantic string */
Collada::InputType GetTypeForSemantic( const std::string& pSemantic); Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
/** Finds the item in the given library by its reference, throws if not found */ /** Finds the item in the given library by its reference, throws if not found */
template <typename Type> const Type& ResolveLibraryReference( template <typename Type> const Type& ResolveLibraryReference(
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const; const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** XML reader, member for everyday use */ /** XML reader, member for everyday use */
irr::io::IrrXMLReader* mReader; irr::io::IrrXMLReader* mReader;
/** All data arrays found in the file by ID. Might be referred to by actually /** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */ everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary; typedef std::map<std::string, Collada::Data> DataLibrary;
DataLibrary mDataLibrary; DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */ /** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary; typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary; AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */ /** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh*> MeshLibrary; typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
MeshLibrary mMeshLibrary; MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */ /** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node*> NodeLibrary; typedef std::map<std::string, Collada::Node*> NodeLibrary;
NodeLibrary mNodeLibrary; NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */ /** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary; typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary; ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */ /** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary; typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary; EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */ /** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary; typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary; MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */ /** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary; typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary; LightLibrary mLightLibrary;
/** Camera library: surface material by ID */ /** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary; typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary; CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */ /** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary; typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary; ControllerLibrary mControllerLibrary;
/** Pointer to the root node. Don't delete, it just points to one of /** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */ the nodes in the node library. */
Collada::Node* mRootNode; Collada::Node* mRootNode;
/** Root animation container */ /** Root animation container */
Collada::Animation mAnims; Collada::Animation mAnims;
/** Size unit: how large compared to a meter */ /** Size unit: how large compared to a meter */
float mUnitSize; float mUnitSize;
/** Which is the up vector */ /** Which is the up vector */
enum { UP_X, UP_Y, UP_Z } mUpDirection; enum { UP_X, UP_Y, UP_Z } mUpDirection;
/** Collada file format version */ /** Collada file format version */
Collada::FormatVersion mFormat; Collada::FormatVersion mFormat;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check for element match // Check for element match
inline bool ColladaParser::IsElement( const char* pName) const inline bool ColladaParser::IsElement( const char* pName) const
{ {
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp( mReader->getNodeName(), pName) == 0; return ::strcmp( mReader->getNodeName(), pName) == 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found // Finds the item in the given library by its reference, throws if not found
template <typename Type> template <typename Type>
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const 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); typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
if( it == pLibrary.end()) if( it == pLibrary.end())
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL)); ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
return it->second; return it->second;
} }
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COLLADAPARSER_H_INC #endif // AI_COLLADAPARSER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +1,147 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to compute UV coordinates /** @file Defines a post processing step to compute UV coordinates
from abstract mappings, such as box or spherical*/ from abstract mappings, such as box or spherical*/
#ifndef AI_COMPUTEUVMAPPING_H_INC #ifndef AI_COMPUTEUVMAPPING_H_INC
#define AI_COMPUTEUVMAPPING_H_INC #define AI_COMPUTEUVMAPPING_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/material.h" #include "../include/assimp/material.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
class ComputeUVMappingTest; class ComputeUVMappingTest;
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** ComputeUVMappingProcess - converts special mappings, such as spherical, /** ComputeUVMappingProcess - converts special mappings, such as spherical,
* cylindrical or boxed to proper UV coordinates for rendering. * cylindrical or boxed to proper UV coordinates for rendering.
*/ */
class ComputeUVMappingProcess : public BaseProcess class ComputeUVMappingProcess : public BaseProcess
{ {
public: public:
ComputeUVMappingProcess(); ComputeUVMappingProcess();
~ComputeUVMappingProcess(); ~ComputeUVMappingProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field. /** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise * @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps. * combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not. * @return true if the process is present in this flag fields, false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes spherical UV coordinates for a mesh /** Computes spherical UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes cylindrical UV coordinates for a mesh /** Computes cylindrical UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes planar UV coordinates for a mesh /** Computes planar UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes cubic UV coordinates for a mesh /** Computes cubic UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out); void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
private: private:
// temporary structure to describe a mapping // temporary structure to describe a mapping
struct MappingInfo struct MappingInfo
{ {
MappingInfo(aiTextureMapping _type) MappingInfo(aiTextureMapping _type)
: type (_type) : type (_type)
, axis (0.f,1.f,0.f) , axis (0.f,1.f,0.f)
, uv (0u) , uv (0u)
{} {}
aiTextureMapping type; aiTextureMapping type;
aiVector3D axis; aiVector3D axis;
unsigned int uv; unsigned int uv;
bool operator== (const MappingInfo& other) bool operator== (const MappingInfo& other)
{ {
return type == other.type && axis == other.axis; return type == other.type && axis == other.axis;
} }
}; };
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COMPUTEUVMAPPING_H_INC #endif // AI_COMPUTEUVMAPPING_H_INC

View File

@ -1,331 +1,331 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file MakeLeftHandedProcess.cpp /** @file MakeLeftHandedProcess.cpp
* @brief Implementation of the post processing step to convert all * @brief Implementation of the post processing step to convert all
* imported data to a left-handed coordinate system. * imported data to a left-handed coordinate system.
* *
* Face order & UV flip are also implemented here, for the sake of a * Face order & UV flip are also implemented here, for the sake of a
* better location. * better location.
*/ */
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include "../include/assimp/postprocess.h" #include "../include/assimp/postprocess.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
using namespace Assimp; using namespace Assimp;
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess() MakeLeftHandedProcess::MakeLeftHandedProcess()
: BaseProcess() { : BaseProcess() {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
MakeLeftHandedProcess::~MakeLeftHandedProcess() { MakeLeftHandedProcess::~MakeLeftHandedProcess() {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_MakeLeftHanded); return 0 != (pFlags & aiProcess_MakeLeftHanded);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void MakeLeftHandedProcess::Execute( aiScene* pScene) void MakeLeftHandedProcess::Execute( aiScene* pScene)
{ {
// Check for an existent root node to proceed // Check for an existent root node to proceed
ai_assert(pScene->mRootNode != NULL); ai_assert(pScene->mRootNode != NULL);
DefaultLogger::get()->debug("MakeLeftHandedProcess begin"); DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
// recursively convert all the nodes // recursively convert all the nodes
ProcessNode( pScene->mRootNode, aiMatrix4x4()); ProcessNode( pScene->mRootNode, aiMatrix4x4());
// process the meshes accordingly // process the meshes accordingly
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
ProcessMesh( pScene->mMeshes[a]); ProcessMesh( pScene->mMeshes[a]);
// process the materials accordingly // process the materials accordingly
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a) for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
ProcessMaterial( pScene->mMaterials[a]); ProcessMaterial( pScene->mMaterials[a]);
// transform all animation channels as well // transform all animation channels as well
for( unsigned int a = 0; a < pScene->mNumAnimations; a++) for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
{ {
aiAnimation* anim = pScene->mAnimations[a]; aiAnimation* anim = pScene->mAnimations[a];
for( unsigned int b = 0; b < anim->mNumChannels; b++) for( unsigned int b = 0; b < anim->mNumChannels; b++)
{ {
aiNodeAnim* nodeAnim = anim->mChannels[b]; aiNodeAnim* nodeAnim = anim->mChannels[b];
ProcessAnimation( nodeAnim); ProcessAnimation( nodeAnim);
} }
} }
DefaultLogger::get()->debug("MakeLeftHandedProcess finished"); DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively converts a node, all of its children and all of its meshes // Recursively converts a node, all of its children and all of its meshes
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation) void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
{ {
// mirror all base vectors at the local Z axis // mirror all base vectors at the local Z axis
pNode->mTransformation.c1 = -pNode->mTransformation.c1; pNode->mTransformation.c1 = -pNode->mTransformation.c1;
pNode->mTransformation.c2 = -pNode->mTransformation.c2; pNode->mTransformation.c2 = -pNode->mTransformation.c2;
pNode->mTransformation.c3 = -pNode->mTransformation.c3; pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.c4 = -pNode->mTransformation.c4; pNode->mTransformation.c4 = -pNode->mTransformation.c4;
// now invert the Z axis again to keep the matrix determinant positive. // 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. // The local meshes will be inverted accordingly so that the result should look just fine again.
pNode->mTransformation.a3 = -pNode->mTransformation.a3; pNode->mTransformation.a3 = -pNode->mTransformation.a3;
pNode->mTransformation.b3 = -pNode->mTransformation.b3; pNode->mTransformation.b3 = -pNode->mTransformation.b3;
pNode->mTransformation.c3 = -pNode->mTransformation.c3; pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways... pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
// continue for all children // continue for all children
for( size_t a = 0; a < pNode->mNumChildren; ++a ) { for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation ); ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh to left handed coordinates. // Converts a single mesh to left handed coordinates.
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror positions, normals and stuff along the Z axis // mirror positions, normals and stuff along the Z axis
for( size_t a = 0; a < pMesh->mNumVertices; ++a) for( size_t a = 0; a < pMesh->mNumVertices; ++a)
{ {
pMesh->mVertices[a].z *= -1.0f; pMesh->mVertices[a].z *= -1.0f;
if( pMesh->HasNormals()) if( pMesh->HasNormals())
pMesh->mNormals[a].z *= -1.0f; pMesh->mNormals[a].z *= -1.0f;
if( pMesh->HasTangentsAndBitangents()) if( pMesh->HasTangentsAndBitangents())
{ {
pMesh->mTangents[a].z *= -1.0f; pMesh->mTangents[a].z *= -1.0f;
pMesh->mBitangents[a].z *= -1.0f; pMesh->mBitangents[a].z *= -1.0f;
} }
} }
// mirror offset matrices of all bones // mirror offset matrices of all bones
for( size_t a = 0; a < pMesh->mNumBones; ++a) for( size_t a = 0; a < pMesh->mNumBones; ++a)
{ {
aiBone* bone = pMesh->mBones[a]; aiBone* bone = pMesh->mBones[a];
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3; bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3; bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3; bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1; bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2; bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4; bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
} }
// mirror bitangents as well as they're derived from the texture coords // mirror bitangents as well as they're derived from the texture coords
if( pMesh->HasTangentsAndBitangents()) if( pMesh->HasTangentsAndBitangents())
{ {
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
pMesh->mBitangents[a] *= -1.0f; pMesh->mBitangents[a] *= -1.0f;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single material to left handed coordinates. // Converts a single material to left handed coordinates.
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
{ {
aiMaterial* mat = (aiMaterial*)_mat; aiMaterial* mat = (aiMaterial*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) { for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a]; aiMaterialProperty* prop = mat->mProperties[a];
// Mapping axis for UV mappings? // Mapping axis for UV mappings?
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) { if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */ ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
aiVector3D* pff = (aiVector3D*)prop->mData; aiVector3D* pff = (aiVector3D*)prop->mData;
pff->z *= -1.f; pff->z *= -1.f;
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts the given animation to LH coordinates. // Converts the given animation to LH coordinates.
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim) void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
{ {
// position keys // position keys
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++) for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
pAnim->mPositionKeys[a].mValue.z *= -1.0f; pAnim->mPositionKeys[a].mValue.z *= -1.0f;
// rotation keys // rotation keys
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) 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 /* 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(); aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3; rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2; rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
aiQuaternion rotquat( rotmat); aiQuaternion rotquat( rotmat);
pAnim->mRotationKeys[a].mValue = rotquat; pAnim->mRotationKeys[a].mValue = rotquat;
*/ */
pAnim->mRotationKeys[a].mValue.x *= -1.0f; pAnim->mRotationKeys[a].mValue.x *= -1.0f;
pAnim->mRotationKeys[a].mValue.y *= -1.0f; pAnim->mRotationKeys[a].mValue.y *= -1.0f;
} }
} }
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS #ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// # FlipUVsProcess // # FlipUVsProcess
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FlipUVsProcess::FlipUVsProcess() FlipUVsProcess::FlipUVsProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FlipUVsProcess::~FlipUVsProcess() FlipUVsProcess::~FlipUVsProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FlipUVsProcess::IsActive( unsigned int pFlags) const bool FlipUVsProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FlipUVs); return 0 != (pFlags & aiProcess_FlipUVs);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipUVsProcess::Execute( aiScene* pScene) void FlipUVsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipUVsProcess begin"); DefaultLogger::get()->debug("FlipUVsProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
ProcessMaterial(pScene->mMaterials[i]); ProcessMaterial(pScene->mMaterials[i]);
DefaultLogger::get()->debug("FlipUVsProcess finished"); DefaultLogger::get()->debug("FlipUVsProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single material // Converts a single material
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat) void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
{ {
aiMaterial* mat = (aiMaterial*)_mat; aiMaterial* mat = (aiMaterial*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) { for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a]; aiMaterialProperty* prop = mat->mProperties[a];
if( !prop ) { if( !prop ) {
DefaultLogger::get()->debug( "Property is null" ); DefaultLogger::get()->debug( "Property is null" );
continue; continue;
} }
// UV transformation key? // UV transformation key?
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) { if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */ ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
aiUVTransform* uv = (aiUVTransform*)prop->mData; aiUVTransform* uv = (aiUVTransform*)prop->mData;
// just flip it, that's everything // just flip it, that's everything
uv->mTranslation.y *= -1.f; uv->mTranslation.y *= -1.f;
uv->mRotation *= -1.f; uv->mRotation *= -1.f;
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh // Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror texture y coordinate // mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a ) ) { if( !pMesh->HasTextureCoords( a ) ) {
break; break;
} }
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) { for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y; pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
} }
} }
} }
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS #endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS #ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
// # FlipWindingOrderProcess // # FlipWindingOrderProcess
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FlipWindingOrderProcess::FlipWindingOrderProcess() FlipWindingOrderProcess::FlipWindingOrderProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FlipWindingOrderProcess::~FlipWindingOrderProcess() FlipWindingOrderProcess::~FlipWindingOrderProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FlipWindingOrder); return 0 != (pFlags & aiProcess_FlipWindingOrder);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipWindingOrderProcess::Execute( aiScene* pScene) void FlipWindingOrderProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipWindingOrderProcess begin"); DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
DefaultLogger::get()->debug("FlipWindingOrderProcess finished"); DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh // Converts a single mesh
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh) void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
{ {
// invert the order of all faces in this mesh // invert the order of all faces in this mesh
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{ {
aiFace& face = pMesh->mFaces[a]; aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices / 2; b++) for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]); std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
} }
} }
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS #endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS

View File

@ -1,168 +1,168 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file MakeLeftHandedProcess.h /** @file MakeLeftHandedProcess.h
* @brief Defines a bunch of post-processing steps to handle * @brief Defines a bunch of post-processing steps to handle
* coordinate system conversions. * coordinate system conversions.
* *
* - LH to RH * - LH to RH
* - UV origin upper-left to lower-left * - UV origin upper-left to lower-left
* - face order cw to ccw * - face order cw to ccw
*/ */
#ifndef AI_CONVERTTOLHPROCESS_H_INC #ifndef AI_CONVERTTOLHPROCESS_H_INC
#define AI_CONVERTTOLHPROCESS_H_INC #define AI_CONVERTTOLHPROCESS_H_INC
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "BaseProcess.h" #include "BaseProcess.h"
struct aiMesh; struct aiMesh;
struct aiNodeAnim; struct aiNodeAnim;
struct aiNode; struct aiNode;
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed /** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
* coordinate system. * coordinate system.
* *
* This implies a mirroring of the Z axis of the coordinate system. But to keep * 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 * transformation matrices free from reflections we shift the reflection to other
* places. We mirror the meshes and adapt the rotations. * 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 * @note RH-LH and LH-RH is the same, so this class can be used for both
*/ */
class MakeLeftHandedProcess : public BaseProcess class MakeLeftHandedProcess : public BaseProcess
{ {
public: public:
MakeLeftHandedProcess(); MakeLeftHandedProcess();
~MakeLeftHandedProcess(); ~MakeLeftHandedProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Recursively converts a node and all of its children /** Recursively converts a node and all of its children
*/ */
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation); void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a single mesh to left handed coordinates. /** Converts a single mesh to left handed coordinates.
* This means that positions, normals and tangents are mirrored at * This means that positions, normals and tangents are mirrored at
* the local Z axis and the order of all faces are inverted. * the local Z axis and the order of all faces are inverted.
* @param pMesh The mesh to convert. * @param pMesh The mesh to convert.
*/ */
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a single material to left-handed coordinates /** Converts a single material to left-handed coordinates
* @param pMat Material to convert * @param pMat Material to convert
*/ */
void ProcessMaterial( aiMaterial* pMat); void ProcessMaterial( aiMaterial* pMat);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts the given animation to LH coordinates. /** Converts the given animation to LH coordinates.
* The rotation and translation keys are transformed, the scale keys * The rotation and translation keys are transformed, the scale keys
* work in local space and can therefore be left untouched. * work in local space and can therefore be left untouched.
* @param pAnim The bone animation to transform * @param pAnim The bone animation to transform
*/ */
void ProcessAnimation( aiNodeAnim* pAnim); void ProcessAnimation( aiNodeAnim* pAnim);
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Postprocessing step to flip the face order of the imported data /** Postprocessing step to flip the face order of the imported data
*/ */
class FlipWindingOrderProcess : public BaseProcess class FlipWindingOrderProcess : public BaseProcess
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
FlipWindingOrderProcess(); FlipWindingOrderProcess();
/** Destructor, private as well */ /** Destructor, private as well */
~FlipWindingOrderProcess(); ~FlipWindingOrderProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Postprocessing step to flip the UV coordinate system of the import data /** Postprocessing step to flip the UV coordinate system of the import data
*/ */
class FlipUVsProcess : public BaseProcess class FlipUVsProcess : public BaseProcess
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
FlipUVsProcess(); FlipUVsProcess();
/** Destructor, private as well */ /** Destructor, private as well */
~FlipUVsProcess(); ~FlipUVsProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
void ProcessMaterial( aiMaterial* mat); void ProcessMaterial( aiMaterial* mat);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_CONVERTTOLHPROCESS_H_INC #endif // AI_CONVERTTOLHPROCESS_H_INC

View File

@ -1,233 +1,233 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file DXFHelper.h /** @file DXFHelper.h
* @brief Internal utilities for the DXF loader. * @brief Internal utilities for the DXF loader.
*/ */
#ifndef INCLUDED_DXFHELPER_H #ifndef INCLUDED_DXFHELPER_H
#define INCLUDED_DXFHELPER_H #define INCLUDED_DXFHELPER_H
#include "LineSplitter.h" #include "LineSplitter.h"
#include "TinyFormatter.h" #include "TinyFormatter.h"
#include "StreamReader.h" #include "StreamReader.h"
#include "fast_atof.h" #include "fast_atof.h"
#include <vector> #include <vector>
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
namespace Assimp { namespace Assimp {
namespace DXF { namespace DXF {
// read pairs of lines, parse group code and value and provide utilities // read pairs of lines, parse group code and value and provide utilities
// to convert the data to the target data type. // to convert the data to the target data type.
class LineReader class LineReader
{ {
public: public:
LineReader(StreamReaderLE& reader) LineReader(StreamReaderLE& reader)
// do NOT skip empty lines. In DXF files, they count as valid data. // do NOT skip empty lines. In DXF files, they count as valid data.
: splitter(reader,false,true) : splitter(reader,false,true)
, end() , end()
{ {
} }
public: public:
// ----------------------------------------- // -----------------------------------------
bool Is(int gc, const char* what) const { bool Is(int gc, const char* what) const {
return groupcode == gc && !strcmp(what,value.c_str()); return groupcode == gc && !strcmp(what,value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
bool Is(int gc) const { bool Is(int gc) const {
return groupcode == gc; return groupcode == gc;
} }
// ----------------------------------------- // -----------------------------------------
int GroupCode() const { int GroupCode() const {
return groupcode; return groupcode;
} }
// ----------------------------------------- // -----------------------------------------
const std::string& Value() const { const std::string& Value() const {
return value; return value;
} }
// ----------------------------------------- // -----------------------------------------
bool End() const { bool End() const {
return !((bool)*this); return !((bool)*this);
} }
public: public:
// ----------------------------------------- // -----------------------------------------
unsigned int ValueAsUnsignedInt() const { unsigned int ValueAsUnsignedInt() const {
return strtoul10(value.c_str()); return strtoul10(value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
int ValueAsSignedInt() const { int ValueAsSignedInt() const {
return strtol10(value.c_str()); return strtol10(value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
float ValueAsFloat() const { float ValueAsFloat() const {
return fast_atof(value.c_str()); return fast_atof(value.c_str());
} }
public: public:
// ----------------------------------------- // -----------------------------------------
/** pseudo-iterator increment to advance to the next (groupcode/value) pair */ /** pseudo-iterator increment to advance to the next (groupcode/value) pair */
LineReader& operator++() { LineReader& operator++() {
if (end) { if (end) {
if (end == 1) { if (end == 1) {
++end; ++end;
} }
return *this; return *this;
} }
try { try {
groupcode = strtol10(splitter->c_str()); groupcode = strtol10(splitter->c_str());
splitter++; splitter++;
value = *splitter; value = *splitter;
splitter++; splitter++;
// automatically skip over {} meta blocks (these are for application use // automatically skip over {} meta blocks (these are for application use
// and currently not relevant for Assimp). // and currently not relevant for Assimp).
if (value.length() && value[0] == '{') { if (value.length() && value[0] == '{') {
size_t cnt = 0; size_t cnt = 0;
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
splitter++; splitter++;
DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
} }
} catch(std::logic_error&) { } catch(std::logic_error&) {
ai_assert(!splitter); ai_assert(!splitter);
} }
if (!splitter) { if (!splitter) {
end = 1; end = 1;
} }
return *this; return *this;
} }
// ----------------------------------------- // -----------------------------------------
LineReader& operator++(int) { LineReader& operator++(int) {
return ++(*this); return ++(*this);
} }
// ----------------------------------------- // -----------------------------------------
operator bool() const { operator bool() const {
return end <= 1; return end <= 1;
} }
private: private:
LineSplitter splitter; LineSplitter splitter;
int groupcode; int groupcode;
std::string value; std::string value;
int end; int end;
}; };
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed. // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
struct PolyLine struct PolyLine
{ {
PolyLine() PolyLine()
: flags() : flags()
{} {}
std::vector<aiVector3D> positions; std::vector<aiVector3D> positions;
std::vector<aiColor4D> colors; std::vector<aiColor4D> colors;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
std::vector<unsigned int> counts; std::vector<unsigned int> counts;
unsigned int flags; unsigned int flags;
std::string layer; std::string layer;
std::string desc; std::string desc;
}; };
// reference to a BLOCK. Specifies its own coordinate system. // reference to a BLOCK. Specifies its own coordinate system.
struct InsertBlock struct InsertBlock
{ {
InsertBlock() InsertBlock()
: scale(1.f,1.f,1.f) : scale(1.f,1.f,1.f)
, angle() , angle()
{} {}
aiVector3D pos; aiVector3D pos;
aiVector3D scale; aiVector3D scale;
float angle; float angle;
std::string name; std::string name;
}; };
// keeps track of all geometry in a single BLOCK. // keeps track of all geometry in a single BLOCK.
struct Block struct Block
{ {
std::vector< boost::shared_ptr<PolyLine> > lines; std::vector< boost::shared_ptr<PolyLine> > lines;
std::vector<InsertBlock> insertions; std::vector<InsertBlock> insertions;
std::string name; std::string name;
aiVector3D base; aiVector3D base;
}; };
struct FileData struct FileData
{ {
// note: the LAST block always contains the stuff from ENTITIES. // note: the LAST block always contains the stuff from ENTITIES.
std::vector<Block> blocks; std::vector<Block> blocks;
}; };
}} }}
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +1,152 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file DXFLoader.h /** @file DXFLoader.h
* @brief Declaration of the .dxf importer class. * @brief Declaration of the .dxf importer class.
*/ */
#ifndef AI_DXFLOADER_H_INCLUDED #ifndef AI_DXFLOADER_H_INCLUDED
#define AI_DXFLOADER_H_INCLUDED #define AI_DXFLOADER_H_INCLUDED
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp { namespace Assimp {
namespace DXF { namespace DXF {
class LineReader; class LineReader;
struct FileData; struct FileData;
struct PolyLine; struct PolyLine;
struct Block; struct Block;
struct InsertBlock; struct InsertBlock;
typedef std::map<std::string, const DXF::Block*> BlockMap; typedef std::map<std::string, const DXF::Block*> BlockMap;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** DXF importer implementation. /** DXF importer implementation.
* *
*/ */
class DXFImporter : public BaseImporter class DXFImporter : public BaseImporter
{ {
public: public:
DXFImporter(); DXFImporter();
~DXFImporter(); ~DXFImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details*/ * See #BaseImporter::GetInfo for the details*/
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details */ * See BaseImporter::InternReadFile() for details */
void InternReadFile( const std::string& pFile, void InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
// ----------------------------------------------------- // -----------------------------------------------------
void SkipSection(DXF::LineReader& reader); void SkipSection(DXF::LineReader& reader);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseHeader(DXF::LineReader& reader, void ParseHeader(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseEntities(DXF::LineReader& reader, void ParseEntities(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseBlocks(DXF::LineReader& reader, void ParseBlocks(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseBlock(DXF::LineReader& reader, void ParseBlock(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseInsertion(DXF::LineReader& reader, void ParseInsertion(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParsePolyLine(DXF::LineReader& reader, void ParsePolyLine(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParsePolyLineVertex(DXF::LineReader& reader, void ParsePolyLineVertex(DXF::LineReader& reader,
DXF::PolyLine& line); DXF::PolyLine& line);
// ----------------------------------------------------- // -----------------------------------------------------
void Parse3DFace(DXF::LineReader& reader, void Parse3DFace(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ConvertMeshes(aiScene* pScene, void ConvertMeshes(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void GenerateHierarchy(aiScene* pScene, void GenerateHierarchy(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void GenerateMaterials(aiScene* pScene, void GenerateMaterials(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ExpandBlockReferences(DXF::Block& bl, void ExpandBlockReferences(DXF::Block& bl,
const DXF::BlockMap& blocks_by_name); const DXF::BlockMap& blocks_by_name);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

View File

@ -1,465 +1,465 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/// @file DeboneProcess.cpp /// @file DeboneProcess.cpp
/** Implementation of the DeboneProcess post processing step */ /** Implementation of the DeboneProcess post processing step */
// internal headers of the post-processing framework // internal headers of the post-processing framework
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "DeboneProcess.h" #include "DeboneProcess.h"
#include <stdio.h> #include <stdio.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
DeboneProcess::DeboneProcess() DeboneProcess::DeboneProcess()
{ {
mNumBones = 0; mNumBones = 0;
mNumBonesCanDoWithout = 0; mNumBonesCanDoWithout = 0;
mThreshold = AI_DEBONE_THRESHOLD; mThreshold = AI_DEBONE_THRESHOLD;
mAllOrNone = false; mAllOrNone = false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
DeboneProcess::~DeboneProcess() DeboneProcess::~DeboneProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool DeboneProcess::IsActive( unsigned int pFlags) const bool DeboneProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_Debone) != 0; return (pFlags & aiProcess_Debone) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void DeboneProcess::SetupProperties(const Importer* pImp) void DeboneProcess::SetupProperties(const Importer* pImp)
{ {
// get the current value of the property // get the current value of the property
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false; mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD); mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void DeboneProcess::Execute( aiScene* pScene) void DeboneProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("DeboneProcess begin"); DefaultLogger::get()->debug("DeboneProcess begin");
if(!pScene->mNumMeshes) { if(!pScene->mNumMeshes) {
return; return;
} }
std::vector<bool> splitList(pScene->mNumMeshes); std::vector<bool> splitList(pScene->mNumMeshes);
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
splitList[a] = ConsiderMesh( pScene->mMeshes[a] ); splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
} }
int numSplits = 0; int numSplits = 0;
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) { if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) { for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if(splitList[a]) { if(splitList[a]) {
numSplits++; numSplits++;
} }
} }
} }
if(numSplits) { if(numSplits) {
// we need to do something. Let's go. // we need to do something. Let's go.
//mSubMeshIndices.clear(); // really needed? //mSubMeshIndices.clear(); // really needed?
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
// build a new array of meshes for the scene // build a new array of meshes for the scene
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
for(unsigned int a=0;a<pScene->mNumMeshes;a++) for(unsigned int a=0;a<pScene->mNumMeshes;a++)
{ {
aiMesh* srcMesh = pScene->mMeshes[a]; aiMesh* srcMesh = pScene->mMeshes[a];
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes; std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
if(splitList[a]) { if(splitList[a]) {
SplitMesh(srcMesh,newMeshes); SplitMesh(srcMesh,newMeshes);
} }
// mesh was split // mesh was split
if(!newMeshes.empty()) { if(!newMeshes.empty()) {
unsigned int out = 0, in = srcMesh->mNumBones; unsigned int out = 0, in = srcMesh->mNumBones;
// store new meshes and indices of the new meshes // store new meshes and indices of the new meshes
for(unsigned int b=0;b<newMeshes.size();b++) { for(unsigned int b=0;b<newMeshes.size();b++) {
const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0; const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0; aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode); std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode);
mSubMeshIndices[a].push_back(push_pair); mSubMeshIndices[a].push_back(push_pair);
meshes.push_back(newMeshes[b].first); meshes.push_back(newMeshes[b].first);
out+=newMeshes[b].first->mNumBones; out+=newMeshes[b].first->mNumBones;
} }
if(!DefaultLogger::isNullLogger()) { if(!DefaultLogger::isNullLogger()) {
char buffer[1024]; char buffer[1024];
::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out); ::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
DefaultLogger::get()->info(buffer); DefaultLogger::get()->info(buffer);
} }
// and destroy the source mesh. It should be completely contained inside the new submeshes // and destroy the source mesh. It should be completely contained inside the new submeshes
delete srcMesh; delete srcMesh;
} }
else { else {
// Mesh is kept unchanged - store it's new place in the mesh array // Mesh is kept unchanged - store it's new place in the mesh array
mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0)); mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0));
meshes.push_back(srcMesh); meshes.push_back(srcMesh);
} }
} }
// rebuild the scene's mesh array // rebuild the scene's mesh array
pScene->mNumMeshes = meshes.size(); pScene->mNumMeshes = meshes.size();
delete [] pScene->mMeshes; delete [] pScene->mMeshes;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
std::copy( meshes.begin(), meshes.end(), pScene->mMeshes); std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
// recurse through all nodes and translate the node's mesh indices to fit the new mesh array // recurse through all nodes and translate the node's mesh indices to fit the new mesh array
UpdateNode( pScene->mRootNode); UpdateNode( pScene->mRootNode);
} }
DefaultLogger::get()->debug("DeboneProcess end"); DefaultLogger::get()->debug("DeboneProcess end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts bones total/removable in a given mesh. // Counts bones total/removable in a given mesh.
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
{ {
if(!pMesh->HasBones()) { if(!pMesh->HasBones()) {
return false; return false;
} }
bool split = false; bool split = false;
//interstitial faces not permitted //interstitial faces not permitted
bool isInterstitialRequired = false; bool isInterstitialRequired = false;
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
const unsigned int cUnowned = UINT_MAX; const unsigned int cUnowned = UINT_MAX;
const unsigned int cCoowned = UINT_MAX-1; const unsigned int cCoowned = UINT_MAX-1;
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight; float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) { if(w==0.0f) {
continue; continue;
} }
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
if(w>=mThreshold) { if(w>=mThreshold) {
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
DefaultLogger::get()->warn("Encountered double entry in bone weights"); DefaultLogger::get()->warn("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {
vertexBones[vid] = cCoowned; vertexBones[vid] = cCoowned;
} }
} }
else vertexBones[vid] = i; else vertexBones[vid] = i;
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isBoneNecessary[i] = w<mThreshold; isBoneNecessary[i] = w<mThreshold;
} }
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isInterstitialRequired = true; isInterstitialRequired = true;
} }
} }
if(isInterstitialRequired) { if(isInterstitialRequired) {
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
if(v!=w) { if(v!=w) {
if(v<pMesh->mNumBones) isBoneNecessary[v] = true; if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
if(w<pMesh->mNumBones) isBoneNecessary[w] = true; if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
} }
} }
} }
} }
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
mNumBonesCanDoWithout++; mNumBonesCanDoWithout++;
split = true; split = true;
} }
mNumBones++; mNumBones++;
} }
return split; return split;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Splits the given mesh by bone count. // Splits the given mesh by bone count.
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
{ {
// same deal here as ConsiderMesh basically // same deal here as ConsiderMesh basically
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
const unsigned int cUnowned = UINT_MAX; const unsigned int cUnowned = UINT_MAX;
const unsigned int cCoowned = UINT_MAX-1; const unsigned int cCoowned = UINT_MAX-1;
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight; float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) { if(w==0.0f) {
continue; continue;
} }
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
if(w>=mThreshold) { if(w>=mThreshold) {
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
//DefaultLogger::get()->warn("Encountered double entry in bone weights"); //DefaultLogger::get()->warn("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {
vertexBones[vid] = cCoowned; vertexBones[vid] = cCoowned;
} }
} }
else vertexBones[vid] = i; else vertexBones[vid] = i;
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isBoneNecessary[i] = w<mThreshold; isBoneNecessary[i] = w<mThreshold;
} }
} }
} }
unsigned int nFacesUnowned = 0; unsigned int nFacesUnowned = 0;
std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX); std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0); std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
unsigned int nInterstitial = 1; unsigned int nInterstitial = 1;
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
if(v!=w) { if(v!=w) {
if(v<pMesh->mNumBones) isBoneNecessary[v] = true; if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
if(w<pMesh->mNumBones) isBoneNecessary[w] = true; if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
} }
else nInterstitial++; else nInterstitial++;
} }
if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) { if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) {
faceBones[i] = v; //primitive belongs to bone #v faceBones[i] = v; //primitive belongs to bone #v
facesPerBone[v]++; facesPerBone[v]++;
} }
else nFacesUnowned++; else nFacesUnowned++;
} }
// invalidate any "cojoined" faces // invalidate any "cojoined" faces
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]]) if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]])
{ {
ai_assert(facesPerBone[faceBones[i]]>0); ai_assert(facesPerBone[faceBones[i]]>0);
facesPerBone[faceBones[i]]--; facesPerBone[faceBones[i]]--;
nFacesUnowned++; nFacesUnowned++;
faceBones[i] = cUnowned; faceBones[i] = cUnowned;
} }
} }
if(nFacesUnowned) { if(nFacesUnowned) {
std::vector<unsigned int> subFaces; std::vector<unsigned int> subFaces;
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
if(faceBones[i]==cUnowned) { if(faceBones[i]==cUnowned) {
subFaces.push_back(i); subFaces.push_back(i);
} }
} }
aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0); aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0); std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
poNewMeshes.push_back(push_pair); poNewMeshes.push_back(push_pair);
} }
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
if(!isBoneNecessary[i]&&facesPerBone[i]>0) { if(!isBoneNecessary[i]&&facesPerBone[i]>0) {
std::vector<unsigned int> subFaces; std::vector<unsigned int> subFaces;
for(unsigned int j=0;j<pMesh->mNumFaces;j++) { for(unsigned int j=0;j<pMesh->mNumFaces;j++) {
if(faceBones[j]==i) { if(faceBones[j]==i) {
subFaces.push_back(j); subFaces.push_back(j);
} }
} }
unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES; unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f); aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
//Lifted from PretransformVertices.cpp //Lifted from PretransformVertices.cpp
ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix); ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]); std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
poNewMeshes.push_back(push_pair); poNewMeshes.push_back(push_pair);
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively updates the node's mesh list to account for the changed mesh list // Recursively updates the node's mesh list to account for the changed mesh list
void DeboneProcess::UpdateNode(aiNode* pNode) const void DeboneProcess::UpdateNode(aiNode* pNode) const
{ {
// rebuild the node's mesh index list // rebuild the node's mesh index list
std::vector<unsigned int> newMeshList; std::vector<unsigned int> newMeshList;
// this will require two passes // this will require two passes
unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size(); unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size();
// first pass, look for meshes which have not moved // first pass, look for meshes which have not moved
for(unsigned int a=0;a<m;a++) { for(unsigned int a=0;a<m;a++) {
unsigned int srcIndex = pNode->mMeshes[a]; unsigned int srcIndex = pNode->mMeshes[a];
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex]; const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
unsigned int nSubmeshes = subMeshes.size(); unsigned int nSubmeshes = subMeshes.size();
for(unsigned int b=0;b<nSubmeshes;b++) { for(unsigned int b=0;b<nSubmeshes;b++) {
if(!subMeshes[b].second) { if(!subMeshes[b].second) {
newMeshList.push_back(subMeshes[b].first); newMeshList.push_back(subMeshes[b].first);
} }
} }
} }
// second pass, collect deboned meshes // second pass, collect deboned meshes
for(unsigned int a=0;a<n;a++) for(unsigned int a=0;a<n;a++)
{ {
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a]; const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
unsigned int nSubmeshes = subMeshes.size(); unsigned int nSubmeshes = subMeshes.size();
for(unsigned int b=0;b<nSubmeshes;b++) { for(unsigned int b=0;b<nSubmeshes;b++) {
if(subMeshes[b].second == pNode) { if(subMeshes[b].second == pNode) {
newMeshList.push_back(subMeshes[b].first); newMeshList.push_back(subMeshes[b].first);
} }
} }
} }
if( pNode->mNumMeshes > 0 ) { if( pNode->mNumMeshes > 0 ) {
delete [] pNode->mMeshes; pNode->mMeshes = NULL; delete [] pNode->mMeshes; pNode->mMeshes = NULL;
} }
pNode->mNumMeshes = newMeshList.size(); pNode->mNumMeshes = newMeshList.size();
if(pNode->mNumMeshes) { if(pNode->mNumMeshes) {
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
} }
// do that also recursively for all children // do that also recursively for all children
for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) { for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
UpdateNode( pNode->mChildren[a]); UpdateNode( pNode->mChildren[a]);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Apply the node transformation to a mesh // Apply the node transformation to a mesh
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
{ {
// Check whether we need to transform the coordinates at all // Check whether we need to transform the coordinates at all
if (!mat.IsIdentity()) { if (!mat.IsIdentity()) {
if (mesh->HasPositions()) { if (mesh->HasPositions()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mVertices[i] = mat * mesh->mVertices[i]; mesh->mVertices[i] = mat * mesh->mVertices[i];
} }
} }
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) { if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
aiMatrix4x4 mWorldIT = mat; aiMatrix4x4 mWorldIT = mat;
mWorldIT.Inverse().Transpose(); mWorldIT.Inverse().Transpose();
// TODO: implement Inverse() for aiMatrix3x3 // TODO: implement Inverse() for aiMatrix3x3
aiMatrix3x3 m = aiMatrix3x3(mWorldIT); aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
if (mesh->HasNormals()) { if (mesh->HasNormals()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize(); mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
} }
} }
if (mesh->HasTangentsAndBitangents()) { if (mesh->HasTangentsAndBitangents()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize(); mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize(); mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
} }
} }
} }
} }
} }

View File

@ -1,132 +1,132 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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. */ /** Defines a post processing step to limit the number of bones affecting a single vertex. */
#ifndef AI_DEBONEPROCESS_H_INC #ifndef AI_DEBONEPROCESS_H_INC
#define AI_DEBONEPROCESS_H_INC #define AI_DEBONEPROCESS_H_INC
#include <vector> #include <vector>
#include <utility> #include <utility>
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
class DeboneTest; class DeboneTest;
namespace Assimp namespace Assimp
{ {
#if (!defined AI_DEBONE_THRESHOLD) #if (!defined AI_DEBONE_THRESHOLD)
# define AI_DEBONE_THRESHOLD 1.0f # define AI_DEBONE_THRESHOLD 1.0f
#endif // !! AI_DEBONE_THRESHOLD #endif // !! AI_DEBONE_THRESHOLD
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** This post processing step removes bones nearly losslessly or according to /** This post processing step removes bones nearly losslessly or according to
* a configured threshold. In order to remove the bone, the primitives affected by * a configured threshold. In order to remove the bone, the primitives affected by
* the bone are split from the mesh. The split off (new) mesh is boneless. At any * the bone are split from the mesh. The split off (new) mesh is boneless. At any
* point in time, bones without affect upon a given mesh are to be removed. * point in time, bones without affect upon a given mesh are to be removed.
*/ */
class DeboneProcess : public BaseProcess class DeboneProcess : public BaseProcess
{ {
public: public:
DeboneProcess(); DeboneProcess();
~DeboneProcess(); ~DeboneProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. * @param pFlags The processing flags the importer was called with.
* A bitwise combination of #aiPostProcessSteps. * A bitwise combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, * @return true if the process is present in this flag fields,
* false if not. * false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ExecuteOnScene(). /** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration * The function is a request to the process to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Counts bones total/removable in a given mesh. /** Counts bones total/removable in a given mesh.
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
*/ */
bool ConsiderMesh( const aiMesh* pMesh); bool ConsiderMesh( const aiMesh* pMesh);
/// Splits the given mesh by bone count. /// Splits the given mesh by bone count.
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split. /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary. /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const; void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
/// Recursively updates the node's mesh list to account for the changed mesh list /// Recursively updates the node's mesh list to account for the changed mesh list
void UpdateNode(aiNode* pNode) const; void UpdateNode(aiNode* pNode) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Apply transformation to a mesh // Apply transformation to a mesh
void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const; void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
public: public:
/** Number of bones present in the scene. */ /** Number of bones present in the scene. */
unsigned int mNumBones; unsigned int mNumBones;
unsigned int mNumBonesCanDoWithout; unsigned int mNumBonesCanDoWithout;
float mThreshold; float mThreshold;
bool mAllOrNone; bool mAllOrNone;
/// Per mesh index: Array of indices of the new submeshes. /// Per mesh index: Array of indices of the new submeshes.
std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices; std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_DEBONEPROCESS_H_INC #endif // AI_DEBONEPROCESS_H_INC

View File

@ -1,147 +1,147 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file DefaultIOStream.cpp /** @file DefaultIOStream.cpp
* @brief Default File I/O implementation for #Importer * @brief Default File I/O implementation for #Importer
*/ */
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
using namespace Assimp; using namespace Assimp;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
DefaultIOStream::~DefaultIOStream() DefaultIOStream::~DefaultIOStream()
{ {
if (mFile) { if (mFile) {
::fclose(mFile); ::fclose(mFile);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Read(void* pvBuffer, size_t DefaultIOStream::Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0); return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Write(const void* pvBuffer, size_t DefaultIOStream::Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0); return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
aiReturn DefaultIOStream::Seek(size_t pOffset, aiReturn DefaultIOStream::Seek(size_t pOffset,
aiOrigin pOrigin) aiOrigin pOrigin)
{ {
if (!mFile) { if (!mFile) {
return AI_FAILURE; return AI_FAILURE;
} }
// Just to check whether our enum maps one to one with the CRT constants // Just to check whether our enum maps one to one with the CRT constants
BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR && BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR &&
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET); aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
// do the seek // do the seek
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE); return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Tell() const size_t DefaultIOStream::Tell() const
{ {
if (!mFile) { if (!mFile) {
return 0; return 0;
} }
return ::ftell(mFile); return ::ftell(mFile);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::FileSize() const size_t DefaultIOStream::FileSize() const
{ {
if (! mFile || mFilename.empty()) { if (! mFile || mFilename.empty()) {
return 0; return 0;
} }
if (SIZE_MAX == cachedSize) { if (SIZE_MAX == cachedSize) {
// Although fseek/ftell would allow us to reuse the exising file handle here, // Although fseek/ftell would allow us to reuse the exising file handle here,
// it is generally unsafe because: // it is generally unsafe because:
// - For binary streams, it is not technically well-defined // - For binary streams, it is not technically well-defined
// - For text files the results are meaningless // - For text files the results are meaningless
// That's why we use the safer variant fstat here. // That's why we use the safer variant fstat here.
// //
// See here for details: // See here for details:
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
#if defined _WIN32 && !defined __GNUC__ #if defined _WIN32 && !defined __GNUC__
struct __stat64 fileStat; struct __stat64 fileStat;
int err = _stat64( mFilename.c_str(), &fileStat ); int err = _stat64( mFilename.c_str(), &fileStat );
if (0 != err) if (0 != err)
return 0; return 0;
cachedSize = (size_t) (fileStat.st_size); cachedSize = (size_t) (fileStat.st_size);
#else #else
struct stat fileStat; struct stat fileStat;
int err = stat(mFilename.c_str(), &fileStat ); int err = stat(mFilename.c_str(), &fileStat );
if (0 != err) if (0 != err)
return 0; return 0;
cachedSize = (size_t) (fileStat.st_size); cachedSize = (size_t) (fileStat.st_size);
#endif #endif
} }
return cachedSize; return cachedSize;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void DefaultIOStream::Flush() void DefaultIOStream::Flush()
{ {
if (mFile) { if (mFile) {
::fflush(mFile); ::fflush(mFile);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------

View File

@ -1,142 +1,142 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Default file I/O using fXXX()-family of functions */ /** @file Default file I/O using fXXX()-family of functions */
#ifndef AI_DEFAULTIOSTREAM_H_INC #ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC #define AI_DEFAULTIOSTREAM_H_INC
#include <stdio.h> #include <stdio.h>
#include "../include/assimp/IOStream.hpp" #include "../include/assimp/IOStream.hpp"
#include "../include/assimp/importerdesc.h" #include "../include/assimp/importerdesc.h"
#include "Defines.h" #include "Defines.h"
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
//! @class DefaultIOStream //! @class DefaultIOStream
//! @brief Default IO implementation, use standard IO operations //! @brief Default IO implementation, use standard IO operations
//! @note An instance of this class can exist without a valid file handle //! @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 //! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions. //! used with no restrictions.
class DefaultIOStream : public IOStream class DefaultIOStream : public IOStream
{ {
friend class DefaultIOSystem; friend class DefaultIOSystem;
#if __ANDROID__ #if __ANDROID__
#if __ANDROID_API__ > 9 #if __ANDROID_API__ > 9
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) #if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
friend class AndroidJNIIOSystem; friend class AndroidJNIIOSystem;
#endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) #endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
#endif // __ANDROID_API__ > 9 #endif // __ANDROID_API__ > 9
#endif // __ANDROID__ #endif // __ANDROID__
protected: protected:
DefaultIOStream(); DefaultIOStream();
DefaultIOStream(FILE* pFile, const std::string &strFilename); DefaultIOStream(FILE* pFile, const std::string &strFilename);
public: public:
/** Destructor public to allow simple deletion to close the file. */ /** Destructor public to allow simple deletion to close the file. */
~DefaultIOStream (); ~DefaultIOStream ();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Read from stream /// Read from stream
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount); size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Write to stream /// Write to stream
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount); size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Seek specific position /// Seek specific position
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset,
aiOrigin pOrigin); aiOrigin pOrigin);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get current seek position /// Get current seek position
size_t Tell() const; size_t Tell() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get size of file /// Get size of file
size_t FileSize() const; size_t FileSize() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Flush file contents /// Flush file contents
void Flush(); void Flush();
private: private:
// File datastructure, using clib // File datastructure, using clib
FILE* mFile; FILE* mFile;
// Filename // Filename
std::string mFilename; std::string mFilename;
// Cached file size // Cached file size
mutable size_t cachedSize; mutable size_t cachedSize;
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream () : inline DefaultIOStream::DefaultIOStream () :
mFile (NULL), mFile (NULL),
mFilename (""), mFilename (""),
cachedSize (SIZE_MAX) cachedSize (SIZE_MAX)
{ {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream (FILE* pFile, inline DefaultIOStream::DefaultIOStream (FILE* pFile,
const std::string &strFilename) : const std::string &strFilename) :
mFile(pFile), mFile(pFile),
mFilename(strFilename), mFilename(strFilename),
cachedSize (SIZE_MAX) cachedSize (SIZE_MAX)
{ {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // ns assimp } // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC #endif //!!AI_DEFAULTIOSTREAM_H_INC

View File

@ -1,197 +1,197 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Default implementation of IOSystem using the standard C file functions */ /** @file Default implementation of IOSystem using the standard C file functions */
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
#include "StringComparison.h" #include "StringComparison.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <stdlib.h> #include <stdlib.h>
#ifdef __unix__ #ifdef __unix__
#include <sys/param.h> #include <sys/param.h>
#include <stdlib.h> #include <stdlib.h>
#endif #endif
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor. // Constructor.
DefaultIOSystem::DefaultIOSystem() DefaultIOSystem::DefaultIOSystem()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
DefaultIOSystem::~DefaultIOSystem() DefaultIOSystem::~DefaultIOSystem()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path. // Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists( const char* pFile) const bool DefaultIOSystem::Exists( const char* pFile) const
{ {
FILE* file = ::fopen( pFile, "rb"); FILE* file = ::fopen( pFile, "rb");
if( !file) if( !file)
return false; return false;
::fclose( file); ::fclose( file);
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Open a new file with a given path. // Open a new file with a given path.
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode) IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
{ {
ai_assert(NULL != strFile); ai_assert(NULL != strFile);
ai_assert(NULL != strMode); ai_assert(NULL != strMode);
FILE* file = ::fopen( strFile, strMode); FILE* file = ::fopen( strFile, strMode);
if( NULL == file) if( NULL == file)
return NULL; return NULL;
return new DefaultIOStream(file, (std::string) strFile); return new DefaultIOStream(file, (std::string) strFile);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it. // Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close( IOStream* pFile) void DefaultIOSystem::Close( IOStream* pFile)
{ {
delete pFile; delete pFile;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the operation specific directory separator // Returns the operation specific directory separator
char DefaultIOSystem::getOsSeparator() const char DefaultIOSystem::getOsSeparator() const
{ {
#ifndef _WIN32 #ifndef _WIN32
return '/'; return '/';
#else #else
return '\\'; return '\\';
#endif #endif
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function) // IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths (const char* one, const char* second) const bool IOSystem::ComparePaths (const char* one, const char* second) const
{ {
return !ASSIMP_stricmp(one,second); return !ASSIMP_stricmp(one,second);
} }
// maximum path length // maximum path length
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html // XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
#ifdef PATH_MAX #ifdef PATH_MAX
# define PATHLIMIT PATH_MAX # define PATHLIMIT PATH_MAX
#else #else
# define PATHLIMIT 4096 # define PATHLIMIT 4096
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path // Convert a relative path into an absolute path
inline void MakeAbsolutePath (const char* in, char* _out) inline void MakeAbsolutePath (const char* in, char* _out)
{ {
ai_assert(in && _out); ai_assert(in && _out);
char* ret; char* ret;
#ifdef _WIN32 #ifdef _WIN32
ret = ::_fullpath(_out, in,PATHLIMIT); ret = ::_fullpath(_out, in,PATHLIMIT);
#else #else
// use realpath // use realpath
ret = realpath(in, _out); ret = realpath(in, _out);
#endif #endif
if(!ret) { if(!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
DefaultLogger::get()->warn("Invalid path: "+std::string(in)); DefaultLogger::get()->warn("Invalid path: "+std::string(in));
strcpy(_out,in); strcpy(_out,in);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation // DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
{ {
// chances are quite good both paths are formatted identically, // chances are quite good both paths are formatted identically,
// so we can hopefully return here already // so we can hopefully return here already
if( !ASSIMP_stricmp(one,second) ) if( !ASSIMP_stricmp(one,second) )
return true; return true;
char temp1[PATHLIMIT]; char temp1[PATHLIMIT];
char temp2[PATHLIMIT]; char temp2[PATHLIMIT];
MakeAbsolutePath (one, temp1); MakeAbsolutePath (one, temp1);
MakeAbsolutePath (second, temp2); MakeAbsolutePath (second, temp2);
return !ASSIMP_stricmp(temp1,temp2); return !ASSIMP_stricmp(temp1,temp2);
} }
std::string DefaultIOSystem::fileName(std::string path) std::string DefaultIOSystem::fileName(std::string path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(last + 1); if (last != std::string::npos) ret = ret.substr(last + 1);
return ret; return ret;
} }
std::string DefaultIOSystem::completeBaseName(std::string path) std::string DefaultIOSystem::completeBaseName(std::string path)
{ {
std::string ret = fileName(path); std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.'); std::size_t pos = ret.find_last_of('.');
if(pos != ret.npos) ret = ret.substr(0, pos); if(pos != ret.npos) ret = ret.substr(0, pos);
return ret; return ret;
} }
std::string DefaultIOSystem::absolutePath(std::string path) std::string DefaultIOSystem::absolutePath(std::string path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(0, last); if (last != std::string::npos) ret = ret.substr(0, last);
return ret; return ret;
} }
#undef PATHLIMIT #undef PATHLIMIT

View File

@ -1,98 +1,98 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Default implementation of IOSystem using the standard C file functions */ /** @file Default implementation of IOSystem using the standard C file functions */
#ifndef AI_DEFAULTIOSYSTEM_H_INC #ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC #define AI_DEFAULTIOSYSTEM_H_INC
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Default implementation of IOSystem using the standard C file functions */ /** Default implementation of IOSystem using the standard C file functions */
class DefaultIOSystem : public IOSystem class DefaultIOSystem : public IOSystem
{ {
public: public:
/** Constructor. */ /** Constructor. */
DefaultIOSystem(); DefaultIOSystem();
/** Destructor. */ /** Destructor. */
~DefaultIOSystem(); ~DefaultIOSystem();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Tests for the existence of a file at the given path. */ /** Tests for the existence of a file at the given path. */
bool Exists( const char* pFile) const; bool Exists( const char* pFile) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const; char getOsSeparator() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Open a new file with a given path. */ /** Open a new file with a given path. */
IOStream* Open( const char* pFile, const char* pMode = "rb"); IOStream* Open( const char* pFile, const char* pMode = "rb");
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Closes the given file and releases all resources associated with it. */ /** Closes the given file and releases all resources associated with it. */
void Close( IOStream* pFile); void Close( IOStream* pFile);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Compare two paths */ /** Compare two paths */
bool ComparePaths (const char* one, const char* second) const; bool ComparePaths (const char* one, const char* second) const;
/** @brief get the file name of a full filepath /** @brief get the file name of a full filepath
* example: /tmp/archive.tar.gz -> archive.tar.gz * example: /tmp/archive.tar.gz -> archive.tar.gz
*/ */
static std::string fileName(std::string path); static std::string fileName(std::string path);
/** @brief get the complete base name of a full filepath /** @brief get the complete base name of a full filepath
* example: /tmp/archive.tar.gz -> archive.tar * example: /tmp/archive.tar.gz -> archive.tar
*/ */
static std::string completeBaseName(std::string path); static std::string completeBaseName(std::string path);
/** @brief get the path of a full filepath /** @brief get the path of a full filepath
* example: /tmp/archive.tar.gz -> /tmp/ * example: /tmp/archive.tar.gz -> /tmp/
*/ */
static std::string absolutePath(std::string path); static std::string absolutePath(std::string path);
}; };
} //!ns Assimp } //!ns Assimp
#endif //AI_DEFAULTIOSYSTEM_H_INC #endif //AI_DEFAULTIOSYSTEM_H_INC

View File

@ -1,423 +1,423 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file DefaultLogger.cpp /** @file DefaultLogger.cpp
* @brief Implementation of DefaultLogger (and Logger) * @brief Implementation of DefaultLogger (and Logger)
*/ */
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
// Default log streams // Default log streams
#include "Win32DebugLogStream.h" #include "Win32DebugLogStream.h"
#include "StdOStreamLogStream.h" #include "StdOStreamLogStream.h"
#include "FileLogStream.h" #include "FileLogStream.h"
#include "../include/assimp/NullLogger.hpp" #include "../include/assimp/NullLogger.hpp"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
# include <boost/thread/thread.hpp> # include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp> # include <boost/thread/mutex.hpp>
boost::mutex loggerMutex; boost::mutex loggerMutex;
#endif #endif
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
NullLogger DefaultLogger::s_pNullLogger; NullLogger DefaultLogger::s_pNullLogger;
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger; Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Represents a log-stream + its error severity // Represents a log-stream + its error severity
struct LogStreamInfo struct LogStreamInfo
{ {
unsigned int m_uiErrorSeverity; unsigned int m_uiErrorSeverity;
LogStream *m_pStream; LogStream *m_pStream;
// Constructor // Constructor
LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) : LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
m_uiErrorSeverity( uiErrorSev ), m_uiErrorSeverity( uiErrorSev ),
m_pStream( pStream ) m_pStream( pStream )
{ {
// empty // empty
} }
// Destructor // Destructor
~LogStreamInfo() ~LogStreamInfo()
{ {
delete m_pStream; delete m_pStream;
} }
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Construct a default log stream // Construct a default log stream
LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams, LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
const char* name /*= "AssimpLog.txt"*/, const char* name /*= "AssimpLog.txt"*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
switch (streams) switch (streams)
{ {
// This is a platform-specific feature // This is a platform-specific feature
case aiDefaultLogStream_DEBUGGER: case aiDefaultLogStream_DEBUGGER:
#ifdef WIN32 #ifdef WIN32
return new Win32DebugLogStream(); return new Win32DebugLogStream();
#else #else
return NULL; return NULL;
#endif #endif
// Platform-independent default streams // Platform-independent default streams
case aiDefaultLogStream_STDERR: case aiDefaultLogStream_STDERR:
return new StdOStreamLogStream(std::cerr); return new StdOStreamLogStream(std::cerr);
case aiDefaultLogStream_STDOUT: case aiDefaultLogStream_STDOUT:
return new StdOStreamLogStream(std::cout); return new StdOStreamLogStream(std::cout);
case aiDefaultLogStream_FILE: case aiDefaultLogStream_FILE:
return (name && *name ? new FileLogStream(name,io) : NULL); return (name && *name ? new FileLogStream(name,io) : NULL);
default: default:
// We don't know this default log stream, so raise an assertion // We don't know this default log stream, so raise an assertion
ai_assert(false); ai_assert(false);
}; };
// For compilers without dead code path detection // For compilers without dead code path detection
return NULL; return NULL;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Creates the only singleton instance // Creates the only singleton instance
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/, Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
LogSeverity severity /*= NORMAL*/, LogSeverity severity /*= NORMAL*/,
unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/, unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (m_pLogger && !isNullLogger() ) if (m_pLogger && !isNullLogger() )
delete m_pLogger; delete m_pLogger;
m_pLogger = new DefaultLogger( severity ); m_pLogger = new DefaultLogger( severity );
// Attach default log streams // Attach default log streams
// Stream the log to the MSVC debugger? // Stream the log to the MSVC debugger?
if (defStreams & aiDefaultLogStream_DEBUGGER) if (defStreams & aiDefaultLogStream_DEBUGGER)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
// Stream the log to COUT? // Stream the log to COUT?
if (defStreams & aiDefaultLogStream_STDOUT) if (defStreams & aiDefaultLogStream_STDOUT)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
// Stream the log to CERR? // Stream the log to CERR?
if (defStreams & aiDefaultLogStream_STDERR) if (defStreams & aiDefaultLogStream_STDERR)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
// Stream the log to a file // Stream the log to a file
if (defStreams & aiDefaultLogStream_FILE && name && *name) if (defStreams & aiDefaultLogStream_FILE && name && *name)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
return m_pLogger; return m_pLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::debug(const char* message) { void Logger::debug(const char* message) {
// SECURITY FIX: otherwise it's easy to produce overruns since // SECURITY FIX: otherwise it's easy to produce overruns since
// sometimes importers will include data from the input file // sometimes importers will include data from the input file
// (i.e. node names) in their messages. // (i.e. node names) in their messages.
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnDebug(message); return OnDebug(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::info(const char* message) { void Logger::info(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnInfo(message); return OnInfo(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::warn(const char* message) { void Logger::warn(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnWarn(message); return OnWarn(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::error(const char* message) { void Logger::error(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnError(message); return OnError(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void DefaultLogger::set( Logger *logger ) void DefaultLogger::set( Logger *logger )
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (!logger)logger = &s_pNullLogger; if (!logger)logger = &s_pNullLogger;
if (m_pLogger && !isNullLogger() ) if (m_pLogger && !isNullLogger() )
delete m_pLogger; delete m_pLogger;
DefaultLogger::m_pLogger = logger; DefaultLogger::m_pLogger = logger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
bool DefaultLogger::isNullLogger() bool DefaultLogger::isNullLogger()
{ {
return m_pLogger == &s_pNullLogger; return m_pLogger == &s_pNullLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Singleton getter // Singleton getter
Logger *DefaultLogger::get() Logger *DefaultLogger::get()
{ {
return m_pLogger; return m_pLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Kills the only instance // Kills the only instance
void DefaultLogger::kill() void DefaultLogger::kill()
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (m_pLogger == &s_pNullLogger)return; if (m_pLogger == &s_pNullLogger)return;
delete m_pLogger; delete m_pLogger;
m_pLogger = &s_pNullLogger; m_pLogger = &s_pNullLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Debug message // Debug message
void DefaultLogger::OnDebug( const char* message ) void DefaultLogger::OnDebug( const char* message )
{ {
if ( m_Severity == Logger::NORMAL ) if ( m_Severity == Logger::NORMAL )
return; return;
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Debugging ); WriteToStreams( msg, Logger::Debugging );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs an info // Logs an info
void DefaultLogger::OnInfo( const char* message ) void DefaultLogger::OnInfo( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Info, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Info, T%u: %s", GetThreadID(), message );
WriteToStreams( msg , Logger::Info ); WriteToStreams( msg , Logger::Info );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs a warning // Logs a warning
void DefaultLogger::OnWarn( const char* message ) void DefaultLogger::OnWarn( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Warn ); WriteToStreams( msg, Logger::Warn );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs an error // Logs an error
void DefaultLogger::OnError( const char* message ) void DefaultLogger::OnError( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Error, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Error, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Err ); WriteToStreams( msg, Logger::Err );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Will attach a new stream // Will attach a new stream
bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity ) bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
{ {
if (!pStream) if (!pStream)
return false; return false;
if (0 == severity) { if (0 == severity) {
severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
} }
for ( StreamIt it = m_StreamArray.begin(); for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it ) ++it )
{ {
if ( (*it)->m_pStream == pStream ) if ( (*it)->m_pStream == pStream )
{ {
(*it)->m_uiErrorSeverity |= severity; (*it)->m_uiErrorSeverity |= severity;
return true; return true;
} }
} }
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream ); LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
m_StreamArray.push_back( pInfo ); m_StreamArray.push_back( pInfo );
return true; return true;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Detatch a stream // Detatch a stream
bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity ) bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{ {
if (!pStream) if (!pStream)
return false; return false;
if (0 == severity) { if (0 == severity) {
severity = SeverityAll; severity = SeverityAll;
} }
for ( StreamIt it = m_StreamArray.begin(); for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it ) ++it )
{ {
if ( (*it)->m_pStream == pStream ) if ( (*it)->m_pStream == pStream )
{ {
(*it)->m_uiErrorSeverity &= ~severity; (*it)->m_uiErrorSeverity &= ~severity;
if ( (*it)->m_uiErrorSeverity == 0 ) if ( (*it)->m_uiErrorSeverity == 0 )
{ {
// don't delete the underlying stream 'cause the caller gains ownership again // don't delete the underlying stream 'cause the caller gains ownership again
(**it).m_pStream = NULL; (**it).m_pStream = NULL;
delete *it; delete *it;
m_StreamArray.erase( it ); m_StreamArray.erase( it );
break; break;
} }
return true; return true;
} }
} }
return false; return false;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Constructor // Constructor
DefaultLogger::DefaultLogger(LogSeverity severity) DefaultLogger::DefaultLogger(LogSeverity severity)
: Logger ( severity ) : Logger ( severity )
, noRepeatMsg (false) , noRepeatMsg (false)
, lastLen( 0 ) , lastLen( 0 )
{ {
lastMsg[0] = '\0'; lastMsg[0] = '\0';
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Destructor // Destructor
DefaultLogger::~DefaultLogger() DefaultLogger::~DefaultLogger()
{ {
for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) { for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
// also frees the underlying stream, we are its owner. // also frees the underlying stream, we are its owner.
delete *it; delete *it;
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Writes message to stream // Writes message to stream
void DefaultLogger::WriteToStreams(const char *message, void DefaultLogger::WriteToStreams(const char *message,
ErrorSeverity ErrorSev ) ErrorSeverity ErrorSev )
{ {
ai_assert(NULL != message); ai_assert(NULL != message);
// Check whether this is a repeated message // Check whether this is a repeated message
if (! ::strncmp( message,lastMsg, lastLen-1)) if (! ::strncmp( message,lastMsg, lastLen-1))
{ {
if (!noRepeatMsg) if (!noRepeatMsg)
{ {
noRepeatMsg = true; noRepeatMsg = true;
message = "Skipping one or more lines with the same contents\n"; message = "Skipping one or more lines with the same contents\n";
} }
else return; else return;
} }
else else
{ {
// append a new-line character to the message to be printed // append a new-line character to the message to be printed
lastLen = ::strlen(message); lastLen = ::strlen(message);
::memcpy(lastMsg,message,lastLen+1); ::memcpy(lastMsg,message,lastLen+1);
::strcat(lastMsg+lastLen,"\n"); ::strcat(lastMsg+lastLen,"\n");
message = lastMsg; message = lastMsg;
noRepeatMsg = false; noRepeatMsg = false;
++lastLen; ++lastLen;
} }
for ( ConstStreamIt it = m_StreamArray.begin(); for ( ConstStreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it) ++it)
{ {
if ( ErrorSev & (*it)->m_uiErrorSeverity ) if ( ErrorSev & (*it)->m_uiErrorSeverity )
(*it)->m_pStream->write( message); (*it)->m_pStream->write( message);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Returns thread id, if not supported only a zero will be returned. // Returns thread id, if not supported only a zero will be returned.
unsigned int DefaultLogger::GetThreadID() unsigned int DefaultLogger::GetThreadID()
{ {
// fixme: we can get this value via boost::threads // fixme: we can get this value via boost::threads
#ifdef WIN32 #ifdef WIN32
return (unsigned int)::GetCurrentThreadId(); return (unsigned int)::GetCurrentThreadId();
#else #else
return 0; // not supported return 0; // not supported
#endif #endif
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // !namespace Assimp } // !namespace Assimp

View File

@ -1,64 +1,64 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ProgressHandler.hpp /** @file ProgressHandler.hpp
* @brief Abstract base class 'ProgressHandler'. * @brief Abstract base class 'ProgressHandler'.
*/ */
#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H #ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H #define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
#include "../include/assimp/ProgressHandler.hpp" #include "../include/assimp/ProgressHandler.hpp"
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @brief Internal default implementation of the #ProgressHandler interface. */ /** @brief Internal default implementation of the #ProgressHandler interface. */
class DefaultProgressHandler class DefaultProgressHandler
: public ProgressHandler { : public ProgressHandler {
virtual bool Update(float /*percentage*/) { virtual bool Update(float /*percentage*/) {
return false; return false;
} }
}; // !class DefaultProgressHandler }; // !class DefaultProgressHandler
} // Namespace Assimp } // Namespace Assimp
#endif #endif

View File

@ -1,125 +1,125 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2008, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef INCLUDED_EXCEPTIONAL_H #ifndef INCLUDED_EXCEPTIONAL_H
#define INCLUDED_EXCEPTIONAL_H #define INCLUDED_EXCEPTIONAL_H
#include <stdexcept> #include <stdexcept>
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
using std::runtime_error; using std::runtime_error;
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable : 4275) # pragma warning(disable : 4275)
#endif #endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an /** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return * unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */ * NULL instead of a valid aiScene then. */
class DeadlyImportError class DeadlyImportError
: public runtime_error : public runtime_error
{ {
public: public:
/** Constructor with arguments */ /** Constructor with arguments */
explicit DeadlyImportError( const std::string& pErrorText) explicit DeadlyImportError( const std::string& pErrorText)
: runtime_error(pErrorText) : runtime_error(pErrorText)
{ {
} }
private: private:
}; };
typedef DeadlyImportError DeadlyExportError; typedef DeadlyImportError DeadlyExportError;
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(default : 4275) # pragma warning(default : 4275)
#endif #endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> template <typename T>
struct ExceptionSwallower { struct ExceptionSwallower {
T operator ()() const { T operator ()() const {
return T(); return T();
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> template <typename T>
struct ExceptionSwallower<T*> { struct ExceptionSwallower<T*> {
T* operator ()() const { T* operator ()() const {
return NULL; return NULL;
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <> template <>
struct ExceptionSwallower<aiReturn> { struct ExceptionSwallower<aiReturn> {
aiReturn operator ()() const { aiReturn operator ()() const {
try { try {
throw; throw;
} }
catch (std::bad_alloc&) { catch (std::bad_alloc&) {
return aiReturn_OUTOFMEMORY; return aiReturn_OUTOFMEMORY;
} }
catch (...) { catch (...) {
return aiReturn_FAILURE; return aiReturn_FAILURE;
} }
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <> template <>
struct ExceptionSwallower<void> { struct ExceptionSwallower<void> {
void operator ()() const { void operator ()() const {
return; return;
} }
}; };
#define ASSIMP_BEGIN_EXCEPTION_REGION()\ #define ASSIMP_BEGIN_EXCEPTION_REGION()\
{\ {\
try { try {
#define ASSIMP_END_EXCEPTION_REGION(type)\ #define ASSIMP_END_EXCEPTION_REGION(type)\
} catch(...) {\ } catch(...) {\
return ExceptionSwallower<type>()();\ return ExceptionSwallower<type>()();\
}\ }\
} }
#endif // INCLUDED_EXCEPTIONAL_H #endif // INCLUDED_EXCEPTIONAL_H

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +1,65 @@
#ifndef ASSIMP_FILELOGSTREAM_H_INC #ifndef ASSIMP_FILELOGSTREAM_H_INC
#define ASSIMP_FILELOGSTREAM_H_INC #define ASSIMP_FILELOGSTREAM_H_INC
#include "../include/assimp/LogStream.hpp" #include "../include/assimp/LogStream.hpp"
#include "../include/assimp/IOStream.hpp" #include "../include/assimp/IOStream.hpp"
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** @class FileLogStream /** @class FileLogStream
* @brief Logstream to write into a file. * @brief Logstream to write into a file.
*/ */
class FileLogStream : class FileLogStream :
public LogStream public LogStream
{ {
public: public:
FileLogStream( const char* file, IOSystem* io = NULL ); FileLogStream( const char* file, IOSystem* io = NULL );
~FileLogStream(); ~FileLogStream();
void write( const char* message ); void write( const char* message );
private: private:
IOStream *m_pStream; IOStream *m_pStream;
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Constructor // Constructor
inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) : inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) :
m_pStream(NULL) m_pStream(NULL)
{ {
if ( !file || 0 == *file ) if ( !file || 0 == *file )
return; return;
// If no IOSystem is specified: take a default one // If no IOSystem is specified: take a default one
if (!io) if (!io)
{ {
DefaultIOSystem FileSystem; DefaultIOSystem FileSystem;
m_pStream = FileSystem.Open( file, "wt"); m_pStream = FileSystem.Open( file, "wt");
} }
else m_pStream = io->Open( file, "wt" ); else m_pStream = io->Open( file, "wt" );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Destructor // Destructor
inline FileLogStream::~FileLogStream() inline FileLogStream::~FileLogStream()
{ {
// The virtual d'tor should destroy the underlying file // The virtual d'tor should destroy the underlying file
delete m_pStream; delete m_pStream;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Write method // Write method
inline void FileLogStream::write( const char* message ) inline void FileLogStream::write( const char* message )
{ {
if (m_pStream != NULL) if (m_pStream != NULL)
{ {
m_pStream->Write(message, sizeof(char), ::strlen(message)); m_pStream->Write(message, sizeof(char), ::strlen(message));
m_pStream->Flush(); m_pStream->Flush();
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // !Namespace Assimp } // !Namespace Assimp
#endif // !! ASSIMP_FILELOGSTREAM_H_INC #endif // !! ASSIMP_FILELOGSTREAM_H_INC

View File

@ -1,300 +1,300 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2008, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file FileSystemFilter.h /** @file FileSystemFilter.h
* Implements a filter system to filter calls to Exists() and Open() * Implements a filter system to filter calls to Exists() and Open()
* in order to improve the sucess rate of file opening ... * in order to improve the sucess rate of file opening ...
*/ */
#ifndef AI_FILESYSTEMFILTER_H_INC #ifndef AI_FILESYSTEMFILTER_H_INC
#define AI_FILESYSTEMFILTER_H_INC #define AI_FILESYSTEMFILTER_H_INC
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "fast_atof.h" #include "fast_atof.h"
#include "ParsingUtils.h" #include "ParsingUtils.h"
namespace Assimp { namespace Assimp {
inline bool IsHex(char s) { inline bool IsHex(char s) {
return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F'); return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F');
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** File system filter /** File system filter
*/ */
class FileSystemFilter : public IOSystem class FileSystemFilter : public IOSystem
{ {
public: public:
/** Constructor. */ /** Constructor. */
FileSystemFilter(const std::string& file, IOSystem* old) FileSystemFilter(const std::string& file, IOSystem* old)
: wrapped (old) : wrapped (old)
, src_file (file) , src_file (file)
, sep(wrapped->getOsSeparator()) , sep(wrapped->getOsSeparator())
{ {
ai_assert(NULL != wrapped); ai_assert(NULL != wrapped);
// Determine base directory // Determine base directory
base = src_file; base = src_file;
std::string::size_type ss2; std::string::size_type ss2;
if (std::string::npos != (ss2 = base.find_last_of("\\/"))) { if (std::string::npos != (ss2 = base.find_last_of("\\/"))) {
base.erase(ss2,base.length()-ss2); base.erase(ss2,base.length()-ss2);
} }
else { else {
base = ""; base = "";
// return; // return;
} }
// make sure the directory is terminated properly // make sure the directory is terminated properly
char s; char s;
if (base.length() == 0) { if (base.length() == 0) {
base = "."; base = ".";
base += getOsSeparator(); base += getOsSeparator();
} }
else if ((s = *(base.end()-1)) != '\\' && s != '/') { else if ((s = *(base.end()-1)) != '\\' && s != '/') {
base += getOsSeparator(); base += getOsSeparator();
} }
DefaultLogger::get()->info("Import root directory is \'" + base + "\'"); DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
} }
/** Destructor. */ /** Destructor. */
~FileSystemFilter() ~FileSystemFilter()
{ {
// haha // haha
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Tests for the existence of a file at the given path. */ /** Tests for the existence of a file at the given path. */
bool Exists( const char* pFile) const bool Exists( const char* pFile) const
{ {
std::string tmp = pFile; std::string tmp = pFile;
// Currently this IOSystem is also used to open THE ONE FILE. // Currently this IOSystem is also used to open THE ONE FILE.
if (tmp != src_file) { if (tmp != src_file) {
BuildPath(tmp); BuildPath(tmp);
Cleanup(tmp); Cleanup(tmp);
} }
return wrapped->Exists(tmp); return wrapped->Exists(tmp);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const char getOsSeparator() const
{ {
return sep; return sep;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Open a new file with a given path. */ /** Open a new file with a given path. */
IOStream* Open( const char* pFile, const char* pMode = "rb") IOStream* Open( const char* pFile, const char* pMode = "rb")
{ {
ai_assert(pFile); ai_assert(pFile);
ai_assert(pMode); ai_assert(pMode);
// First try the unchanged path // First try the unchanged path
IOStream* s = wrapped->Open(pFile,pMode); IOStream* s = wrapped->Open(pFile,pMode);
if (!s) { if (!s) {
std::string tmp = pFile; std::string tmp = pFile;
// Try to convert between absolute and relative paths // Try to convert between absolute and relative paths
BuildPath(tmp); BuildPath(tmp);
s = wrapped->Open(tmp,pMode); s = wrapped->Open(tmp,pMode);
if (!s) { if (!s) {
// Finally, look for typical issues with paths // Finally, look for typical issues with paths
// and try to correct them. This is our last // and try to correct them. This is our last
// resort. // resort.
tmp = pFile; tmp = pFile;
Cleanup(tmp); Cleanup(tmp);
BuildPath(tmp); BuildPath(tmp);
s = wrapped->Open(tmp,pMode); s = wrapped->Open(tmp,pMode);
} }
} }
return s; return s;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Closes the given file and releases all resources associated with it. */ /** Closes the given file and releases all resources associated with it. */
void Close( IOStream* pFile) void Close( IOStream* pFile)
{ {
return wrapped->Close(pFile); return wrapped->Close(pFile);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Compare two paths */ /** Compare two paths */
bool ComparePaths (const char* one, const char* second) const bool ComparePaths (const char* one, const char* second) const
{ {
return wrapped->ComparePaths (one,second); return wrapped->ComparePaths (one,second);
} }
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build a valid path from a given relative or absolute path. /** Build a valid path from a given relative or absolute path.
*/ */
void BuildPath (std::string& in) const void BuildPath (std::string& in) const
{ {
// if we can already access the file, great. // if we can already access the file, great.
if (in.length() < 3 || wrapped->Exists(in)) { if (in.length() < 3 || wrapped->Exists(in)) {
return; return;
} }
// Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows). // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows).
if (in[1] != ':') { if (in[1] != ':') {
// append base path and try // append base path and try
const std::string tmp = base + in; const std::string tmp = base + in;
if (wrapped->Exists(tmp)) { if (wrapped->Exists(tmp)) {
in = tmp; in = tmp;
return; return;
} }
} }
// Chop of the file name and look in the model directory, if // Chop of the file name and look in the model directory, if
// this fails try all sub paths of the given path, i.e. // this fails try all sub paths of the given path, i.e.
// if the given path is foo/bar/something.lwo, try // if the given path is foo/bar/something.lwo, try
// <base>/something.lwo // <base>/something.lwo
// <base>/bar/something.lwo // <base>/bar/something.lwo
// <base>/foo/bar/something.lwo // <base>/foo/bar/something.lwo
std::string::size_type pos = in.rfind('/'); std::string::size_type pos = in.rfind('/');
if (std::string::npos == pos) { if (std::string::npos == pos) {
pos = in.rfind('\\'); pos = in.rfind('\\');
} }
if (std::string::npos != pos) { if (std::string::npos != pos) {
std::string tmp; std::string tmp;
std::string::size_type last_dirsep = std::string::npos; std::string::size_type last_dirsep = std::string::npos;
while(true) { while(true) {
tmp = base; tmp = base;
tmp += sep; tmp += sep;
std::string::size_type dirsep = in.rfind('/', last_dirsep); std::string::size_type dirsep = in.rfind('/', last_dirsep);
if (std::string::npos == dirsep) { if (std::string::npos == dirsep) {
dirsep = in.rfind('\\', last_dirsep); dirsep = in.rfind('\\', last_dirsep);
} }
if (std::string::npos == dirsep || dirsep == 0) { if (std::string::npos == dirsep || dirsep == 0) {
// we did try this already. // we did try this already.
break; break;
} }
last_dirsep = dirsep-1; last_dirsep = dirsep-1;
tmp += in.substr(dirsep+1, in.length()-pos); tmp += in.substr(dirsep+1, in.length()-pos);
if (wrapped->Exists(tmp)) { if (wrapped->Exists(tmp)) {
in = tmp; in = tmp;
return; return;
} }
} }
} }
// hopefully the underlying file system has another few tricks to access this file ... // hopefully the underlying file system has another few tricks to access this file ...
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Cleanup the given path /** Cleanup the given path
*/ */
void Cleanup (std::string& in) const void Cleanup (std::string& in) const
{ {
char last = 0; char last = 0;
if(in.empty()) { if(in.empty()) {
return; return;
} }
// Remove a very common issue when we're parsing file names: spaces at the // Remove a very common issue when we're parsing file names: spaces at the
// beginning of the path. // beginning of the path.
std::string::iterator it = in.begin(); std::string::iterator it = in.begin();
while (IsSpaceOrNewLine( *it ))++it; while (IsSpaceOrNewLine( *it ))++it;
if (it != in.begin()) { if (it != in.begin()) {
in.erase(in.begin(),it+1); in.erase(in.begin(),it+1);
} }
const char sep = getOsSeparator(); const char sep = getOsSeparator();
for (it = in.begin(); it != in.end(); ++it) { for (it = in.begin(); it != in.end(); ++it) {
// Exclude :// and \\, which remain untouched. // Exclude :// and \\, which remain untouched.
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
if ( !strncmp(&*it, "://", 3 )) { if ( !strncmp(&*it, "://", 3 )) {
it += 3; it += 3;
continue; continue;
} }
if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) { if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) {
it += 2; it += 2;
continue; continue;
} }
// Cleanup path delimiters // Cleanup path delimiters
if (*it == '/' || (*it) == '\\') { if (*it == '/' || (*it) == '\\') {
*it = sep; *it = sep;
// And we're removing double delimiters, frequent issue with // And we're removing double delimiters, frequent issue with
// incorrectly composited paths ... // incorrectly composited paths ...
if (last == *it) { if (last == *it) {
it = in.erase(it); it = in.erase(it);
--it; --it;
} }
} }
else if (*it == '%' && in.end() - it > 2) { else if (*it == '%' && in.end() - it > 2) {
// Hex sequence in URIs // Hex sequence in URIs
if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) { if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
*it = HexOctetToDecimal(&*it); *it = HexOctetToDecimal(&*it);
it = in.erase(it+1,it+2); it = in.erase(it+1,it+2);
--it; --it;
} }
} }
last = *it; last = *it;
} }
} }
private: private:
IOSystem* wrapped; IOSystem* wrapped;
std::string src_file, base; std::string src_file, base;
char sep; char sep;
}; };
} //!ns Assimp } //!ns Assimp
#endif //AI_DEFAULTIOSYSTEM_H_INC #endif //AI_DEFAULTIOSYSTEM_H_INC

View File

@ -1,217 +1,217 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file FindDegenerates.cpp /** @file FindDegenerates.cpp
* @brief Implementation of the FindDegenerates post-process step. * @brief Implementation of the FindDegenerates post-process step.
*/ */
// internal headers // internal headers
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "FindDegenerates.h" #include "FindDegenerates.h"
#include "Exceptional.h" #include "Exceptional.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FindDegeneratesProcess::FindDegeneratesProcess() FindDegeneratesProcess::FindDegeneratesProcess()
: configRemoveDegenerates (false) : configRemoveDegenerates (false)
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FindDegeneratesProcess::~FindDegeneratesProcess() FindDegeneratesProcess::~FindDegeneratesProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FindDegenerates); return 0 != (pFlags & aiProcess_FindDegenerates);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup import configuration // Setup import configuration
void FindDegeneratesProcess::SetupProperties(const Importer* pImp) void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
{ {
// Get the current value of AI_CONFIG_PP_FD_REMOVE // Get the current value of AI_CONFIG_PP_FD_REMOVE
configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0)); configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindDegeneratesProcess::Execute( aiScene* pScene) void FindDegeneratesProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FindDegeneratesProcess begin"); DefaultLogger::get()->debug("FindDegeneratesProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){ for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
ExecuteOnMesh( pScene->mMeshes[i]); ExecuteOnMesh( pScene->mMeshes[i]);
} }
DefaultLogger::get()->debug("FindDegeneratesProcess finished"); DefaultLogger::get()->debug("FindDegeneratesProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported mesh // Executes the post processing step on the given imported mesh
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
{ {
mesh->mPrimitiveTypes = 0; mesh->mPrimitiveTypes = 0;
std::vector<bool> remove_me; std::vector<bool> remove_me;
if (configRemoveDegenerates) if (configRemoveDegenerates)
remove_me.resize(mesh->mNumFaces,false); remove_me.resize(mesh->mNumFaces,false);
unsigned int deg = 0, limit; unsigned int deg = 0, limit;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{ {
aiFace& face = mesh->mFaces[a]; aiFace& face = mesh->mFaces[a];
bool first = true; bool first = true;
// check whether the face contains degenerated entries // check whether the face contains degenerated entries
for (unsigned int i = 0; i < face.mNumIndices; ++i) for (unsigned int i = 0; i < face.mNumIndices; ++i)
{ {
// Polygons with more than 4 points are allowed to have double points, that is // Polygons with more than 4 points are allowed to have double points, that is
// simulating polygons with holes just with concave polygons. However, // simulating polygons with holes just with concave polygons. However,
// double points may not come directly after another. // double points may not come directly after another.
limit = face.mNumIndices; limit = face.mNumIndices;
if (face.mNumIndices > 4) if (face.mNumIndices > 4)
limit = std::min(limit,i+2); limit = std::min(limit,i+2);
for (unsigned int t = i+1; t < limit; ++t) for (unsigned int t = i+1; t < limit; ++t)
{ {
if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]]) if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
{ {
// we have found a matching vertex position // we have found a matching vertex position
// remove the corresponding index from the array // remove the corresponding index from the array
--face.mNumIndices;--limit; --face.mNumIndices;--limit;
for (unsigned int m = t; m < face.mNumIndices; ++m) for (unsigned int m = t; m < face.mNumIndices; ++m)
{ {
face.mIndices[m] = face.mIndices[m+1]; face.mIndices[m] = face.mIndices[m+1];
} }
--t; --t;
// NOTE: we set the removed vertex index to an unique value // NOTE: we set the removed vertex index to an unique value
// to make sure the developer gets notified when his // to make sure the developer gets notified when his
// application attemps to access this data. // application attemps to access this data.
face.mIndices[face.mNumIndices] = 0xdeadbeef; face.mIndices[face.mNumIndices] = 0xdeadbeef;
if(first) if(first)
{ {
++deg; ++deg;
first = false; first = false;
} }
if (configRemoveDegenerates) { if (configRemoveDegenerates) {
remove_me[a] = true; remove_me[a] = true;
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby! goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
} }
} }
} }
} }
// We need to update the primitive flags array of the mesh. // We need to update the primitive flags array of the mesh.
switch (face.mNumIndices) switch (face.mNumIndices)
{ {
case 1u: case 1u:
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break; break;
case 2u: case 2u:
mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
break; break;
case 3u: case 3u:
mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
break; break;
default: default:
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
break; break;
}; };
evil_jump_outside: evil_jump_outside:
continue; continue;
} }
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
if (configRemoveDegenerates && deg) { if (configRemoveDegenerates && deg) {
unsigned int n = 0; unsigned int n = 0;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{ {
aiFace& face_src = mesh->mFaces[a]; aiFace& face_src = mesh->mFaces[a];
if (!remove_me[a]) { if (!remove_me[a]) {
aiFace& face_dest = mesh->mFaces[n++]; aiFace& face_dest = mesh->mFaces[n++];
// Do a manual copy, keep the index array // Do a manual copy, keep the index array
face_dest.mNumIndices = face_src.mNumIndices; face_dest.mNumIndices = face_src.mNumIndices;
face_dest.mIndices = face_src.mIndices; face_dest.mIndices = face_src.mIndices;
if (&face_src != &face_dest) { if (&face_src != &face_dest) {
// clear source // clear source
face_src.mNumIndices = 0; face_src.mNumIndices = 0;
face_src.mIndices = NULL; face_src.mIndices = NULL;
} }
} }
else { else {
// Otherwise delete it if we don't need this face // Otherwise delete it if we don't need this face
delete[] face_src.mIndices; delete[] face_src.mIndices;
face_src.mIndices = NULL; face_src.mIndices = NULL;
face_src.mNumIndices = 0; face_src.mNumIndices = 0;
} }
} }
// Just leave the rest of the array unreferenced, we don't care for now // Just leave the rest of the array unreferenced, we don't care for now
mesh->mNumFaces = n; mesh->mNumFaces = n;
if (!mesh->mNumFaces) { if (!mesh->mNumFaces) {
// WTF!? // WTF!?
// OK ... for completeness and because I'm not yet tired, // OK ... for completeness and because I'm not yet tired,
// let's write code that willl hopefully never be called // let's write code that willl hopefully never be called
// (famous last words) // (famous last words)
// OK ... bad idea. // OK ... bad idea.
throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?"); throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
} }
} }
if (deg && !DefaultLogger::isNullLogger()) if (deg && !DefaultLogger::isNullLogger())
{ {
char s[64]; char s[64];
ASSIMP_itoa10(s,deg); ASSIMP_itoa10(s,deg);
DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives"); DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
} }
} }

View File

@ -1,105 +1,105 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to search all meshes for /** @file Defines a post processing step to search all meshes for
degenerated faces */ degenerated faces */
#ifndef AI_FINDDEGENERATESPROCESS_H_INC #ifndef AI_FINDDEGENERATESPROCESS_H_INC
#define AI_FINDDEGENERATESPROCESS_H_INC #define AI_FINDDEGENERATESPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
class FindDegeneratesProcessTest; class FindDegeneratesProcessTest;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** FindDegeneratesProcess: Searches a mesh for degenerated triangles. /** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
*/ */
class ASSIMP_API FindDegeneratesProcess : public BaseProcess class ASSIMP_API FindDegeneratesProcess : public BaseProcess
{ {
public: public:
FindDegeneratesProcess(); FindDegeneratesProcess();
~FindDegeneratesProcess(); ~FindDegeneratesProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Check whether step is active // Check whether step is active
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Execute step on a given scene // Execute step on a given scene
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup import settings // Setup import settings
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Execute step on a given mesh // Execute step on a given mesh
void ExecuteOnMesh( aiMesh* mesh); void ExecuteOnMesh( aiMesh* mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Enable the instant removal of degenerated primitives /** @brief Enable the instant removal of degenerated primitives
* @param d hm ... difficult to guess what this means, hu!? * @param d hm ... difficult to guess what this means, hu!?
*/ */
void EnableInstantRemoval(bool d) { void EnableInstantRemoval(bool d) {
configRemoveDegenerates = d; configRemoveDegenerates = d;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Check whether instant removal is currently enabled /** @brief Check whether instant removal is currently enabled
* @return ... * @return ...
*/ */
bool IsInstantRemoval() const { bool IsInstantRemoval() const {
return configRemoveDegenerates; return configRemoveDegenerates;
} }
private: private:
//! Configuration option: remove degenerates faces immediately //! Configuration option: remove degenerates faces immediately
bool configRemoveDegenerates; bool configRemoveDegenerates;
}; };
} }
#endif // !! AI_FINDDEGENERATESPROCESS_H_INC #endif // !! AI_FINDDEGENERATESPROCESS_H_INC

View File

@ -1,277 +1,277 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file FindInstancesProcess.cpp /** @file FindInstancesProcess.cpp
* @brief Implementation of the aiProcess_FindInstances postprocessing step * @brief Implementation of the aiProcess_FindInstances postprocessing step
*/ */
#include "FindInstancesProcess.h" #include "FindInstancesProcess.h"
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <stdio.h> #include <stdio.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FindInstancesProcess::FindInstancesProcess() FindInstancesProcess::FindInstancesProcess()
: configSpeedFlag (false) : configSpeedFlag (false)
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FindInstancesProcess::~FindInstancesProcess() FindInstancesProcess::~FindInstancesProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FindInstancesProcess::IsActive( unsigned int pFlags) const bool FindInstancesProcess::IsActive( unsigned int pFlags) const
{ {
// FindInstances makes absolutely no sense together with PreTransformVertices // FindInstances makes absolutely no sense together with PreTransformVertices
// fixme: spawn error message somewhere else? // fixme: spawn error message somewhere else?
return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices); return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup properties for the step // Setup properties for the step
void FindInstancesProcess::SetupProperties(const Importer* pImp) void FindInstancesProcess::SetupProperties(const Importer* pImp)
{ {
// AI_CONFIG_FAVOUR_SPEED // AI_CONFIG_FAVOUR_SPEED
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0)); configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Compare the bones of two meshes // Compare the bones of two meshes
bool CompareBones(const aiMesh* orig, const aiMesh* inst) bool CompareBones(const aiMesh* orig, const aiMesh* inst)
{ {
for (unsigned int i = 0; i < orig->mNumBones;++i) { for (unsigned int i = 0; i < orig->mNumBones;++i) {
aiBone* aha = orig->mBones[i]; aiBone* aha = orig->mBones[i];
aiBone* oha = inst->mBones[i]; aiBone* oha = inst->mBones[i];
if (aha->mNumWeights != oha->mNumWeights || if (aha->mNumWeights != oha->mNumWeights ||
aha->mOffsetMatrix != oha->mOffsetMatrix) { aha->mOffsetMatrix != oha->mOffsetMatrix) {
return false; return false;
} }
// compare weight per weight --- // compare weight per weight ---
for (unsigned int n = 0; n < aha->mNumWeights;++n) { for (unsigned int n = 0; n < aha->mNumWeights;++n) {
if (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId || if (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId ||
(aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) { (aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) {
return false; return false;
} }
} }
} }
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Update mesh indices in the node graph // Update mesh indices in the node graph
void UpdateMeshIndices(aiNode* node, unsigned int* lookup) void UpdateMeshIndices(aiNode* node, unsigned int* lookup)
{ {
for (unsigned int n = 0; n < node->mNumMeshes;++n) for (unsigned int n = 0; n < node->mNumMeshes;++n)
node->mMeshes[n] = lookup[node->mMeshes[n]]; node->mMeshes[n] = lookup[node->mMeshes[n]];
for (unsigned int n = 0; n < node->mNumChildren;++n) for (unsigned int n = 0; n < node->mNumChildren;++n)
UpdateMeshIndices(node->mChildren[n],lookup); UpdateMeshIndices(node->mChildren[n],lookup);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindInstancesProcess::Execute( aiScene* pScene) void FindInstancesProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FindInstancesProcess begin"); DefaultLogger::get()->debug("FindInstancesProcess begin");
if (pScene->mNumMeshes) { if (pScene->mNumMeshes) {
// use a pseudo hash for all meshes in the scene to quickly find // use a pseudo hash for all meshes in the scene to quickly find
// the ones which are possibly equal. This step is executed early // the ones which are possibly equal. This step is executed early
// in the pipeline, so we could, depending on the file format, // in the pipeline, so we could, depending on the file format,
// have several thousand small meshes. That's too much for a brute // have several thousand small meshes. That's too much for a brute
// everyone-against-everyone check involving up to 10 comparisons // everyone-against-everyone check involving up to 10 comparisons
// each. // each.
boost::scoped_array<uint64_t> hashes (new uint64_t[pScene->mNumMeshes]); boost::scoped_array<uint64_t> hashes (new uint64_t[pScene->mNumMeshes]);
boost::scoped_array<unsigned int> remapping (new unsigned int[pScene->mNumMeshes]); boost::scoped_array<unsigned int> remapping (new unsigned int[pScene->mNumMeshes]);
unsigned int numMeshesOut = 0; unsigned int numMeshesOut = 0;
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
aiMesh* inst = pScene->mMeshes[i]; aiMesh* inst = pScene->mMeshes[i];
hashes[i] = GetMeshHash(inst); hashes[i] = GetMeshHash(inst);
for (int a = i-1; a >= 0; --a) { for (int a = i-1; a >= 0; --a) {
if (hashes[i] == hashes[a]) if (hashes[i] == hashes[a])
{ {
aiMesh* orig = pScene->mMeshes[a]; aiMesh* orig = pScene->mMeshes[a];
if (!orig) if (!orig)
continue; continue;
// check for hash collision .. we needn't check // check for hash collision .. we needn't check
// the vertex format, it *must* match due to the // the vertex format, it *must* match due to the
// (brilliant) construction of the hash // (brilliant) construction of the hash
if (orig->mNumBones != inst->mNumBones || if (orig->mNumBones != inst->mNumBones ||
orig->mNumFaces != inst->mNumFaces || orig->mNumFaces != inst->mNumFaces ||
orig->mNumVertices != inst->mNumVertices || orig->mNumVertices != inst->mNumVertices ||
orig->mMaterialIndex != inst->mMaterialIndex || orig->mMaterialIndex != inst->mMaterialIndex ||
orig->mPrimitiveTypes != inst->mPrimitiveTypes) orig->mPrimitiveTypes != inst->mPrimitiveTypes)
continue; continue;
// up to now the meshes are equal. find an appropriate // up to now the meshes are equal. find an appropriate
// epsilon to compare position differences against // epsilon to compare position differences against
float epsilon = ComputePositionEpsilon(inst); float epsilon = ComputePositionEpsilon(inst);
epsilon *= epsilon; epsilon *= epsilon;
// now compare vertex positions, normals, // now compare vertex positions, normals,
// tangents and bitangents using this epsilon. // tangents and bitangents using this epsilon.
if (orig->HasPositions()) { if (orig->HasPositions()) {
if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon)) if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
continue; continue;
} }
if (orig->HasNormals()) { if (orig->HasNormals()) {
if(!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon)) if(!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon))
continue; continue;
} }
if (orig->HasTangentsAndBitangents()) { if (orig->HasTangentsAndBitangents()) {
if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) || if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) ||
!CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon)) !CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon))
continue; continue;
} }
// use a constant epsilon for colors and UV coordinates // use a constant epsilon for colors and UV coordinates
static const float uvEpsilon = 10e-4f; static const float uvEpsilon = 10e-4f;
{ {
unsigned int i, end = orig->GetNumUVChannels(); unsigned int i, end = orig->GetNumUVChannels();
for(i = 0; i < end; ++i) { for(i = 0; i < end; ++i) {
if (!orig->mTextureCoords[i]) { if (!orig->mTextureCoords[i]) {
continue; continue;
} }
if(!CompareArrays(orig->mTextureCoords[i],inst->mTextureCoords[i],orig->mNumVertices,uvEpsilon)) { if(!CompareArrays(orig->mTextureCoords[i],inst->mTextureCoords[i],orig->mNumVertices,uvEpsilon)) {
break; break;
} }
} }
if (i != end) { if (i != end) {
continue; continue;
} }
} }
{ {
unsigned int i, end = orig->GetNumColorChannels(); unsigned int i, end = orig->GetNumColorChannels();
for(i = 0; i < end; ++i) { for(i = 0; i < end; ++i) {
if (!orig->mColors[i]) { if (!orig->mColors[i]) {
continue; continue;
} }
if(!CompareArrays(orig->mColors[i],inst->mColors[i],orig->mNumVertices,uvEpsilon)) { if(!CompareArrays(orig->mColors[i],inst->mColors[i],orig->mNumVertices,uvEpsilon)) {
break; break;
} }
} }
if (i != end) { if (i != end) {
continue; continue;
} }
} }
// These two checks are actually quite expensive and almost *never* required. // 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 // Almost. That's why they're still here. But there's no reason to do them
// in speed-targeted imports. // in speed-targeted imports.
if (!configSpeedFlag) { if (!configSpeedFlag) {
// It seems to be strange, but we really need to check whether the // It seems to be strange, but we really need to check whether the
// bones are identical too. Although it's extremely unprobable // bones are identical too. Although it's extremely unprobable
// that they're not if control reaches here, we need to deal // that they're not if control reaches here, we need to deal
// with unprobable cases, too. It could still be that there are // with unprobable cases, too. It could still be that there are
// equal shapes which are deformed differently. // equal shapes which are deformed differently.
if (!CompareBones(orig,inst)) if (!CompareBones(orig,inst))
continue; continue;
// For completeness ... compare even the index buffers for equality // For completeness ... compare even the index buffers for equality
// face order & winding order doesn't care. Input data is in verbose format. // 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_orig(new unsigned int[orig->mNumVertices]);
boost::scoped_array<unsigned int> ftbl_inst(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) { for (unsigned int tt = 0; tt < orig->mNumFaces;++tt) {
aiFace& f = orig->mFaces[tt]; aiFace& f = orig->mFaces[tt];
for (unsigned int nn = 0; nn < f.mNumIndices;++nn) for (unsigned int nn = 0; nn < f.mNumIndices;++nn)
ftbl_orig[f.mIndices[nn]] = tt; ftbl_orig[f.mIndices[nn]] = tt;
aiFace& f2 = inst->mFaces[tt]; aiFace& f2 = inst->mFaces[tt];
for (unsigned int nn = 0; nn < f2.mNumIndices;++nn) for (unsigned int nn = 0; nn < f2.mNumIndices;++nn)
ftbl_inst[f2.mIndices[nn]] = tt; ftbl_inst[f2.mIndices[nn]] = tt;
} }
if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int))) if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int)))
continue; continue;
} }
// We're still here. Or in other words: 'inst' is an instance of 'orig'. // 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. // Place a marker in our list that we can easily update mesh indices.
remapping[i] = remapping[a]; remapping[i] = remapping[a];
// Delete the instanced mesh, we don't need it anymore // Delete the instanced mesh, we don't need it anymore
delete inst; delete inst;
pScene->mMeshes[i] = NULL; pScene->mMeshes[i] = NULL;
break; break;
} }
} }
// If we didn't find a match for the current mesh: keep it // If we didn't find a match for the current mesh: keep it
if (pScene->mMeshes[i]) { if (pScene->mMeshes[i]) {
remapping[i] = numMeshesOut++; remapping[i] = numMeshesOut++;
} }
} }
ai_assert(0 != numMeshesOut); ai_assert(0 != numMeshesOut);
if (numMeshesOut != pScene->mNumMeshes) { if (numMeshesOut != pScene->mNumMeshes) {
// Collapse the meshes array by removing all NULL entries // Collapse the meshes array by removing all NULL entries
for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) { for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) {
if (pScene->mMeshes[i]) if (pScene->mMeshes[i])
pScene->mMeshes[real++] = pScene->mMeshes[i]; pScene->mMeshes[real++] = pScene->mMeshes[i];
} }
// And update the node graph with our nice lookup table // And update the node graph with our nice lookup table
UpdateMeshIndices(pScene->mRootNode,remapping.get()); UpdateMeshIndices(pScene->mRootNode,remapping.get());
// write to log // write to log
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
char buffer[512]; char buffer[512];
::sprintf(buffer,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut); ::sprintf(buffer,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
DefaultLogger::get()->info(buffer); DefaultLogger::get()->info(buffer);
} }
pScene->mNumMeshes = numMeshesOut; pScene->mNumMeshes = numMeshesOut;
} }
else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found"); else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found");
} }
} }

View File

@ -1,135 +1,135 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file FindInstancesProcess.h /** @file FindInstancesProcess.h
* @brief Declares the aiProcess_FindInstances post-process step * @brief Declares the aiProcess_FindInstances post-process step
*/ */
#ifndef AI_FINDINSTANCES_H_INC #ifndef AI_FINDINSTANCES_H_INC
#define AI_FINDINSTANCES_H_INC #define AI_FINDINSTANCES_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
class FindInstancesProcessTest; class FindInstancesProcessTest;
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** @brief Get a pseudo(!)-hash representing a mesh. /** @brief Get a pseudo(!)-hash representing a mesh.
* *
* The hash is built from number of vertices, faces, primitive types, * The hash is built from number of vertices, faces, primitive types,
* .... but *not* from the real mesh data. The funcction is not a perfect hash. * .... but *not* from the real mesh data. The funcction is not a perfect hash.
* @param in Input mesh * @param in Input mesh
* @return Hash. * @return Hash.
*/ */
inline uint64_t GetMeshHash(aiMesh* in) inline uint64_t GetMeshHash(aiMesh* in)
{ {
ai_assert(NULL != in); ai_assert(NULL != in);
// ... get an unique value representing the vertex format of the mesh // ... get an unique value representing the vertex format of the mesh
const unsigned int fhash = GetMeshVFormatUnique(in); const unsigned int fhash = GetMeshVFormatUnique(in);
// and bake it with number of vertices/faces/bones/matidx/ptypes // and bake it with number of vertices/faces/bones/matidx/ptypes
return ((uint64_t)fhash << 32u) | (( return ((uint64_t)fhash << 32u) | ((
(in->mNumBones << 16u) ^ (in->mNumVertices) ^ (in->mNumBones << 16u) ^ (in->mNumVertices) ^
(in->mNumFaces<<4u) ^ (in->mMaterialIndex<<15) ^ (in->mNumFaces<<4u) ^ (in->mMaterialIndex<<15) ^
(in->mPrimitiveTypes<<28)) & 0xffffffff ); (in->mPrimitiveTypes<<28)) & 0xffffffff );
} }
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** @brief Perform a component-wise comparison of two arrays /** @brief Perform a component-wise comparison of two arrays
* *
* @param first First array * @param first First array
* @param second Second aray * @param second Second aray
* @param size Size of both arrays * @param size Size of both arrays
* @param e Epsilon * @param e Epsilon
* @return true if the arrays are identical * @return true if the arrays are identical
*/ */
inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second, inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
unsigned int size, float e) unsigned int size, float e)
{ {
for (const aiVector3D* end = first+size; first != end; ++first,++second) { for (const aiVector3D* end = first+size; first != end; ++first,++second) {
if ( (*first - *second).SquareLength() >= e) if ( (*first - *second).SquareLength() >= e)
return false; return false;
} }
return true; return true;
} }
// and the same for colors ... // and the same for colors ...
inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second, inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
unsigned int size, float e) unsigned int size, float e)
{ {
for (const aiColor4D* end = first+size; first != end; ++first,++second) { for (const aiColor4D* end = first+size; first != end; ++first,++second) {
if ( GetColorDifference(*first,*second) >= e) if ( GetColorDifference(*first,*second) >= e)
return false; return false;
} }
return true; return true;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief A post-processing steps to search for instanced meshes /** @brief A post-processing steps to search for instanced meshes
*/ */
class FindInstancesProcess : public BaseProcess class FindInstancesProcess : public BaseProcess
{ {
public: public:
FindInstancesProcess(); FindInstancesProcess();
~FindInstancesProcess(); ~FindInstancesProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Check whether step is active in given flags combination // Check whether step is active in given flags combination
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Execute step on a given scene // Execute step on a given scene
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup properties prior to executing the process // Setup properties prior to executing the process
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
private: private:
bool configSpeedFlag; bool configSpeedFlag;
}; // ! end class FindInstancesProcess }; // ! end class FindInstancesProcess
} // ! end namespace Assimp } // ! end namespace Assimp
#endif // !! AI_FINDINSTANCES_H_INC #endif // !! AI_FINDINSTANCES_H_INC

View File

@ -1,423 +1,423 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to search an importer's output /** @file Defines a post processing step to search an importer's output
for data that is obviously invalid */ for data that is obviously invalid */
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS #ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
// internal headers // internal headers
#include "FindInvalidDataProcess.h" #include "FindInvalidDataProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "Macros.h" #include "Macros.h"
#include "Exceptional.h" #include "Exceptional.h"
#include "qnan.h" #include "qnan.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FindInvalidDataProcess::FindInvalidDataProcess() FindInvalidDataProcess::FindInvalidDataProcess()
: configEpsilon(0.0f) : configEpsilon(0.0f)
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FindInvalidDataProcess::~FindInvalidDataProcess() FindInvalidDataProcess::~FindInvalidDataProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FindInvalidData); return 0 != (pFlags & aiProcess_FindInvalidData);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup import configuration // Setup import configuration
void FindInvalidDataProcess::SetupProperties(const Importer* pImp) void FindInvalidDataProcess::SetupProperties(const Importer* pImp)
{ {
// Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f)); configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Update mesh references in the node graph // Update mesh references in the node graph
void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping) void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping)
{ {
if (node->mNumMeshes) { if (node->mNumMeshes) {
unsigned int out = 0; unsigned int out = 0;
for (unsigned int a = 0; a < node->mNumMeshes;++a) { for (unsigned int a = 0; a < node->mNumMeshes;++a) {
unsigned int ref = node->mMeshes[a]; unsigned int ref = node->mMeshes[a];
if (UINT_MAX != (ref = meshMapping[ref])) { if (UINT_MAX != (ref = meshMapping[ref])) {
node->mMeshes[out++] = ref; node->mMeshes[out++] = ref;
} }
} }
// just let the members that are unused, that's much cheaper // just let the members that are unused, that's much cheaper
// than a full array realloc'n'copy party ... // than a full array realloc'n'copy party ...
if(!(node->mNumMeshes = out)) { if(!(node->mNumMeshes = out)) {
delete[] node->mMeshes; delete[] node->mMeshes;
node->mMeshes = NULL; node->mMeshes = NULL;
} }
} }
// recursively update all children // recursively update all children
for (unsigned int i = 0; i < node->mNumChildren;++i) { for (unsigned int i = 0; i < node->mNumChildren;++i) {
UpdateMeshReferences(node->mChildren[i],meshMapping); UpdateMeshReferences(node->mChildren[i],meshMapping);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindInvalidDataProcess::Execute( aiScene* pScene) void FindInvalidDataProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FindInvalidDataProcess begin"); DefaultLogger::get()->debug("FindInvalidDataProcess begin");
bool out = false; bool out = false;
std::vector<unsigned int> meshMapping(pScene->mNumMeshes); std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
unsigned int real = 0; unsigned int real = 0;
// Process meshes // Process meshes
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
int result; int result;
if ((result = ProcessMesh( pScene->mMeshes[a]))) { if ((result = ProcessMesh( pScene->mMeshes[a]))) {
out = true; out = true;
if (2 == result) { if (2 == result) {
// remove this mesh // remove this mesh
delete pScene->mMeshes[a]; delete pScene->mMeshes[a];
AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]); AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
meshMapping[a] = UINT_MAX; meshMapping[a] = UINT_MAX;
continue; continue;
} }
} }
pScene->mMeshes[real] = pScene->mMeshes[a]; pScene->mMeshes[real] = pScene->mMeshes[a];
meshMapping[a] = real++; meshMapping[a] = real++;
} }
// Process animations // Process animations
for (unsigned int a = 0; a < pScene->mNumAnimations;++a) { for (unsigned int a = 0; a < pScene->mNumAnimations;++a) {
ProcessAnimation( pScene->mAnimations[a]); ProcessAnimation( pScene->mAnimations[a]);
} }
if (out) { if (out) {
if ( real != pScene->mNumMeshes) { if ( real != pScene->mNumMeshes) {
if (!real) { if (!real) {
throw DeadlyImportError("No meshes remaining"); throw DeadlyImportError("No meshes remaining");
} }
// we need to remove some meshes. // we need to remove some meshes.
// therefore we'll also need to remove all references // therefore we'll also need to remove all references
// to them from the scenegraph // to them from the scenegraph
UpdateMeshReferences(pScene->mRootNode,meshMapping); UpdateMeshReferences(pScene->mRootNode,meshMapping);
pScene->mNumMeshes = real; pScene->mNumMeshes = real;
} }
DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ..."); DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ...");
} }
else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK."); else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK.");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline const char* ValidateArrayContents(const T* arr, unsigned int size, inline const char* ValidateArrayContents(const T* arr, unsigned int size,
const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
{ {
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size, inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size,
const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero ) const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero )
{ {
bool b = false; bool b = false;
unsigned int cnt = 0; unsigned int cnt = 0;
for (unsigned int i = 0; i < size;++i) { for (unsigned int i = 0; i < size;++i) {
if (dirtyMask.size() && dirtyMask[i]) { if (dirtyMask.size() && dirtyMask[i]) {
continue; continue;
} }
++cnt; ++cnt;
const aiVector3D& v = arr[i]; const aiVector3D& v = arr[i];
if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) { 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"; return "INF/NAN was found in a vector component";
} }
if (!mayBeZero && !v.x && !v.y && !v.z ) { if (!mayBeZero && !v.x && !v.y && !v.z ) {
return "Found zero-length vector"; return "Found zero-length vector";
} }
if (i && v != arr[i-1])b = true; if (i && v != arr[i-1])b = true;
} }
if (cnt > 1 && !b && !mayBeIdentical) { if (cnt > 1 && !b && !mayBeIdentical) {
return "All vectors are identical"; return "All vectors are identical";
} }
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline bool ProcessArray(T*& in, unsigned int num,const char* name, inline bool ProcessArray(T*& in, unsigned int num,const char* name,
const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
{ {
const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero); const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero);
if (err) { if (err) {
DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err); DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err);
delete[] in; delete[] in;
in = NULL; in = NULL;
return true; return true;
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon); AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) { AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) {
return std::fabs(n-s)>epsilon; return std::fabs(n-s)>epsilon;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, float epsilon) { bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, float epsilon) {
return return
EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
EpsilonCompare(n.mValue.z,s.mValue.z,epsilon); EpsilonCompare(n.mValue.z,s.mValue.z,epsilon);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, float epsilon) { bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, float epsilon) {
return return
EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) && EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) &&
EpsilonCompare(n.mValue.w,s.mValue.w,epsilon); EpsilonCompare(n.mValue.w,s.mValue.w,epsilon);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline bool AllIdentical(T* in, unsigned int num, float epsilon) inline bool AllIdentical(T* in, unsigned int num, float epsilon)
{ {
if (num <= 1) { if (num <= 1) {
return true; return true;
} }
if (epsilon > 0.f) { if (epsilon > 0.f) {
for (unsigned int i = 0; i < num-1;++i) { for (unsigned int i = 0; i < num-1;++i) {
if (!EpsilonCompare(in[i],in[i+1],epsilon)) { if (!EpsilonCompare(in[i],in[i+1],epsilon)) {
return false; return false;
} }
} }
} }
else { else {
for (unsigned int i = 0; i < num-1;++i) { for (unsigned int i = 0; i < num-1;++i) {
if (in[i] != in[i+1]) { if (in[i] != in[i+1]) {
return false; return false;
} }
} }
} }
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Search an animation for invalid content // Search an animation for invalid content
void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim) void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
{ {
// Process all animation channels // Process all animation channels
for (unsigned int a = 0; a < anim->mNumChannels;++a) { for (unsigned int a = 0; a < anim->mNumChannels;++a) {
ProcessAnimationChannel( anim->mChannels[a]); ProcessAnimationChannel( anim->mChannels[a]);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
{ {
int i = 0; int i = 0;
// ScenePreprocessor's work ... // ScenePreprocessor's work ...
ai_assert((0 != anim->mPositionKeys && 0 != anim->mRotationKeys && 0 != anim->mScalingKeys)); ai_assert((0 != anim->mPositionKeys && 0 != anim->mRotationKeys && 0 != anim->mScalingKeys));
// Check whether all values in a tracks are identical - in this case // Check whether all values in a tracks are identical - in this case
// we can remove al keys except one. // we can remove al keys except one.
// POSITIONS // POSITIONS
if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon)) if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon))
{ {
aiVectorKey v = anim->mPositionKeys[0]; aiVectorKey v = anim->mPositionKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
delete[] anim->mPositionKeys; delete[] anim->mPositionKeys;
anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1]; anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1];
anim->mPositionKeys[0] = v; anim->mPositionKeys[0] = v;
i = 1; i = 1;
} }
// ROTATIONS // ROTATIONS
if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon)) if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon))
{ {
aiQuatKey v = anim->mRotationKeys[0]; aiQuatKey v = anim->mRotationKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
delete[] anim->mRotationKeys; delete[] anim->mRotationKeys;
anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1]; anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1];
anim->mRotationKeys[0] = v; anim->mRotationKeys[0] = v;
i = 1; i = 1;
} }
// SCALINGS // SCALINGS
if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon)) if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon))
{ {
aiVectorKey v = anim->mScalingKeys[0]; aiVectorKey v = anim->mScalingKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
delete[] anim->mScalingKeys; delete[] anim->mScalingKeys;
anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1]; anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1];
anim->mScalingKeys[0] = v; anim->mScalingKeys[0] = v;
i = 1; i = 1;
} }
if (1 == i) if (1 == i)
DefaultLogger::get()->warn("Simplified dummy tracks with just one key"); DefaultLogger::get()->warn("Simplified dummy tracks with just one key");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Search a mesh for invalid contents // Search a mesh for invalid contents
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
{ {
bool ret = false; bool ret = false;
std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false)); std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
// Ignore elements that are not referenced by vertices. // Ignore elements that are not referenced by vertices.
// (they are, for example, caused by the FindDegenerates step) // (they are, for example, caused by the FindDegenerates step)
for (unsigned int m = 0; m < pMesh->mNumFaces;++m) { for (unsigned int m = 0; m < pMesh->mNumFaces;++m) {
const aiFace& f = pMesh->mFaces[m]; const aiFace& f = pMesh->mFaces[m];
for (unsigned int i = 0; i < f.mNumIndices;++i) { for (unsigned int i = 0; i < f.mNumIndices;++i) {
dirtyMask[f.mIndices[i]] = false; dirtyMask[f.mIndices[i]] = false;
} }
} }
// Process vertex positions // Process vertex positions
if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) { if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) {
DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions"); DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
return 2; return 2;
} }
// process texture coordinates // process texture coordinates
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) { for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) {
if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) { if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) {
// delete all subsequent texture coordinate sets. // delete all subsequent texture coordinate sets.
for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL; delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL;
} }
ret = true; ret = true;
} }
} }
// -- we don't validate vertex colors, it's difficult to say whether // -- we don't validate vertex colors, it's difficult to say whether
// they are invalid or not. // they are invalid or not.
// Normals and tangents are undefined for point and line faces. // Normals and tangents are undefined for point and line faces.
if (pMesh->mNormals || pMesh->mTangents) { if (pMesh->mNormals || pMesh->mTangents) {
if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes || if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) aiPrimitiveType_LINE & pMesh->mPrimitiveTypes)
{ {
if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes || if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes)
{ {
// We need to update the lookup-table // We need to update the lookup-table
for (unsigned int m = 0; m < pMesh->mNumFaces;++m) for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
{ {
const aiFace& f = pMesh->mFaces[m]; const aiFace& f = pMesh->mFaces[m];
if (f.mNumIndices < 3) { if (f.mNumIndices < 3) {
dirtyMask[f.mIndices[0]] = true; dirtyMask[f.mIndices[0]] = true;
if (f.mNumIndices == 2) { if (f.mNumIndices == 2) {
dirtyMask[f.mIndices[1]] = true; dirtyMask[f.mIndices[1]] = true;
} }
} }
} }
} }
// Normals, tangents and bitangents are undefined for // Normals, tangents and bitangents are undefined for
// the whole mesh (and should not even be there) // the whole mesh (and should not even be there)
else return ret; else return ret;
} }
// Process mesh normals // Process mesh normals
if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices, if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices,
"normals",dirtyMask,true,false)) "normals",dirtyMask,true,false))
ret = true; ret = true;
// Process mesh tangents // Process mesh tangents
if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) { if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) {
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL; delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
ret = true; ret = true;
} }
// Process mesh bitangents // Process mesh bitangents
if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) { if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) {
delete[] pMesh->mTangents; pMesh->mTangents = NULL; delete[] pMesh->mTangents; pMesh->mTangents = NULL;
ret = true; ret = true;
} }
} }
return ret ? 1 : 0; return ret ? 1 : 0;
} }
#endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS #endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS

View File

@ -1,105 +1,105 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to search an importer's output /** @file Defines a post processing step to search an importer's output
for data that is obviously invalid */ for data that is obviously invalid */
#ifndef AI_FINDINVALIDDATA_H_INC #ifndef AI_FINDINVALIDDATA_H_INC
#define AI_FINDINVALIDDATA_H_INC #define AI_FINDINVALIDDATA_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "../include/assimp/anim.h" #include "../include/assimp/anim.h"
struct aiMesh; struct aiMesh;
class FindInvalidDataProcessTest; class FindInvalidDataProcessTest;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The FindInvalidData post-processing step. It searches the mesh data /** The FindInvalidData post-processing step. It searches the mesh data
* for parts that are obviously invalid and removes them. * for parts that are obviously invalid and removes them.
* *
* Originally this was a workaround for some models written by Blender * Originally this was a workaround for some models written by Blender
* which have zero normal vectors. */ * which have zero normal vectors. */
class ASSIMP_API FindInvalidDataProcess : public BaseProcess class ASSIMP_API FindInvalidDataProcess : public BaseProcess
{ {
public: public:
FindInvalidDataProcess(); FindInvalidDataProcess();
~FindInvalidDataProcess(); ~FindInvalidDataProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// //
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup import settings // Setup import settings
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Run the step // Run the step
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the postprocessing step on the given mesh /** Executes the postprocessing step on the given mesh
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
* @return 0 - nothing, 1 - removed sth, 2 - please delete me */ * @return 0 - nothing, 1 - removed sth, 2 - please delete me */
int ProcessMesh( aiMesh* pMesh); int ProcessMesh( aiMesh* pMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the postprocessing step on the given animation /** Executes the postprocessing step on the given animation
* @param anim The animation to process. */ * @param anim The animation to process. */
void ProcessAnimation (aiAnimation* anim); void ProcessAnimation (aiAnimation* anim);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the postprocessing step on the given anim channel /** Executes the postprocessing step on the given anim channel
* @param anim The animation channel to process.*/ * @param anim The animation channel to process.*/
void ProcessAnimationChannel (aiNodeAnim* anim); void ProcessAnimationChannel (aiNodeAnim* anim);
private: private:
float configEpsilon; float configEpsilon;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_AI_FINDINVALIDDATA_H_INC #endif // AI_AI_FINDINVALIDDATA_H_INC

View File

@ -1,179 +1,179 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the post processing step to invert /** @file Implementation of the post processing step to invert
* all normals in meshes with infacing normals. * all normals in meshes with infacing normals.
*/ */
// internal headers // internal headers
#include "FixNormalsStep.h" #include "FixNormalsStep.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/postprocess.h" #include "../include/assimp/postprocess.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include <stdio.h> #include <stdio.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FixInfacingNormalsProcess::FixInfacingNormalsProcess() FixInfacingNormalsProcess::FixInfacingNormalsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FixInfacingNormalsProcess::~FixInfacingNormalsProcess() FixInfacingNormalsProcess::~FixInfacingNormalsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_FixInfacingNormals) != 0; return (pFlags & aiProcess_FixInfacingNormals) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FixInfacingNormalsProcess::Execute( aiScene* pScene) void FixInfacingNormalsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FixInfacingNormalsProcess begin"); DefaultLogger::get()->debug("FixInfacingNormalsProcess begin");
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
if (bHas) if (bHas)
DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues."); DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues.");
else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene."); else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene.");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Apply the step to the mesh // Apply the step to the mesh
bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
{ {
ai_assert(NULL != pcMesh); ai_assert(NULL != pcMesh);
// Nothing to do if there are no model normals // Nothing to do if there are no model normals
if (!pcMesh->HasNormals())return false; if (!pcMesh->HasNormals())return false;
// Compute the bounding box of both the model vertices + normals and // Compute the bounding box of both the model vertices + normals and
// the umodified model vertices. Then check whether the first BB // the umodified model vertices. Then check whether the first BB
// is smaller than the second. In this case we can assume that the // 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 .. // normals need to be flipped, although there are a few special cases ..
// convex, concave, planar models ... // convex, concave, planar models ...
aiVector3D vMin0 (1e10f,1e10f,1e10f); aiVector3D vMin0 (1e10f,1e10f,1e10f);
aiVector3D vMin1 (1e10f,1e10f,1e10f); aiVector3D vMin1 (1e10f,1e10f,1e10f);
aiVector3D vMax0 (-1e10f,-1e10f,-1e10f); aiVector3D vMax0 (-1e10f,-1e10f,-1e10f);
aiVector3D vMax1 (-1e10f,-1e10f,-1e10f); aiVector3D vMax1 (-1e10f,-1e10f,-1e10f);
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i) for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
{ {
vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x); vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x);
vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y); vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y);
vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z); vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z);
vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x); vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x);
vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y); vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z); vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i]; const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
vMin0.x = std::min(vMin0.x,vWithNormal.x); vMin0.x = std::min(vMin0.x,vWithNormal.x);
vMin0.y = std::min(vMin0.y,vWithNormal.y); vMin0.y = std::min(vMin0.y,vWithNormal.y);
vMin0.z = std::min(vMin0.z,vWithNormal.z); vMin0.z = std::min(vMin0.z,vWithNormal.z);
vMax0.x = std::max(vMax0.x,vWithNormal.x); vMax0.x = std::max(vMax0.x,vWithNormal.x);
vMax0.y = std::max(vMax0.y,vWithNormal.y); vMax0.y = std::max(vMax0.y,vWithNormal.y);
vMax0.z = std::max(vMax0.z,vWithNormal.z); vMax0.z = std::max(vMax0.z,vWithNormal.z);
} }
const float fDelta0_x = (vMax0.x - vMin0.x); const float fDelta0_x = (vMax0.x - vMin0.x);
const float fDelta0_y = (vMax0.y - vMin0.y); const float fDelta0_y = (vMax0.y - vMin0.y);
const float fDelta0_z = (vMax0.z - vMin0.z); const float fDelta0_z = (vMax0.z - vMin0.z);
const float fDelta1_x = (vMax1.x - vMin1.x); const float fDelta1_x = (vMax1.x - vMin1.x);
const float fDelta1_y = (vMax1.y - vMin1.y); const float fDelta1_y = (vMax1.y - vMin1.y);
const float fDelta1_z = (vMax1.z - vMin1.z); const float fDelta1_z = (vMax1.z - vMin1.z);
// Check whether the boxes are overlapping // Check whether the boxes are overlapping
if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false; if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false;
if ((fDelta0_y > 0.0f) != (fDelta1_y > 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; if ((fDelta0_z > 0.0f) != (fDelta1_z > 0.0f))return false;
// Check whether this is a planar surface // Check whether this is a planar surface
const float fDelta1_yz = fDelta1_y * fDelta1_z; const float fDelta1_yz = fDelta1_y * fDelta1_z;
if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false; if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))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; if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
// now compare the volumes of the bounding boxes // now compare the volumes of the bounding boxes
if (std::fabs(fDelta0_x * fDelta1_yz) < if (std::fabs(fDelta0_x * fDelta1_yz) <
std::fabs(fDelta1_x * fDelta1_y * fDelta1_z)) std::fabs(fDelta1_x * fDelta1_y * fDelta1_z))
{ {
if (!DefaultLogger::isNullLogger()) if (!DefaultLogger::isNullLogger())
{ {
char buffer[128]; // should be sufficiently large char buffer[128]; // should be sufficiently large
::sprintf(buffer,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index); ::sprintf(buffer,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index);
DefaultLogger::get()->info(buffer); DefaultLogger::get()->info(buffer);
} }
// Invert normals // Invert normals
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i) for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
pcMesh->mNormals[i] *= -1.0f; pcMesh->mNormals[i] *= -1.0f;
// ... and flip faces // ... and flip faces
for (unsigned int i = 0; i < pcMesh->mNumFaces;++i) for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
{ {
aiFace& face = pcMesh->mFaces[i]; aiFace& face = pcMesh->mFaces[i];
for( unsigned int b = 0; b < face.mNumIndices / 2; b++) for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]); std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
} }
return true; return true;
} }
return false; return false;
} }

View File

@ -1,92 +1,92 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to fix infacing normals */ /** @file Defines a post processing step to fix infacing normals */
#ifndef AI_FIXNORMALSPROCESS_H_INC #ifndef AI_FIXNORMALSPROCESS_H_INC
#define AI_FIXNORMALSPROCESS_H_INC #define AI_FIXNORMALSPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
struct aiMesh; struct aiMesh;
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The FixInfacingNormalsProcess tries to determine whether the normal /** The FixInfacingNormalsProcess tries to determine whether the normal
* vectors of an object are facing inwards. In this case they will be * vectors of an object are facing inwards. In this case they will be
* flipped. * flipped.
*/ */
class FixInfacingNormalsProcess : public BaseProcess class FixInfacingNormalsProcess : public BaseProcess
{ {
public: public:
FixInfacingNormalsProcess(); FixInfacingNormalsProcess();
~FixInfacingNormalsProcess(); ~FixInfacingNormalsProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field. /** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise * @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps. * combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not. * @return true if the process is present in this flag fields, false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the step on the given mesh /** Executes the step on the given mesh
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
*/ */
bool ProcessMesh( aiMesh* pMesh, unsigned int index); bool ProcessMesh( aiMesh* pMesh, unsigned int index);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_FIXNORMALSPROCESS_H_INC #endif // AI_FIXNORMALSPROCESS_H_INC

View File

@ -1,143 +1,143 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the post processing step to generate face /** @file Implementation of the post processing step to generate face
* normals for all imported faces. * normals for all imported faces.
*/ */
#include "GenFaceNormalsProcess.h" #include "GenFaceNormalsProcess.h"
#include "../include/assimp/postprocess.h" #include "../include/assimp/postprocess.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "Exceptional.h" #include "Exceptional.h"
#include "qnan.h" #include "qnan.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
GenFaceNormalsProcess::GenFaceNormalsProcess() GenFaceNormalsProcess::GenFaceNormalsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
GenFaceNormalsProcess::~GenFaceNormalsProcess() GenFaceNormalsProcess::~GenFaceNormalsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_GenNormals) != 0; return (pFlags & aiProcess_GenNormals) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void GenFaceNormalsProcess::Execute( aiScene* pScene) void GenFaceNormalsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("GenFaceNormalsProcess begin"); DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
} }
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if(this->GenMeshFaceNormals( pScene->mMeshes[a])) { if(this->GenMeshFaceNormals( pScene->mMeshes[a])) {
bHas = true; bHas = true;
} }
} }
if (bHas) { if (bHas) {
DefaultLogger::get()->info("GenFaceNormalsProcess finished. " DefaultLogger::get()->info("GenFaceNormalsProcess finished. "
"Face normals have been calculated"); "Face normals have been calculated");
} }
else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. " else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. "
"Normals are already there"); "Normals are already there");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh) bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
{ {
if (NULL != pMesh->mNormals) { if (NULL != pMesh->mNormals) {
return false; return false;
} }
// If the mesh consists of lines and/or points but not of // If the mesh consists of lines and/or points but not of
// triangles or higher-order polygons the normal vectors // triangles or higher-order polygons the normal vectors
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) { if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes"); DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
return false; return false;
} }
// allocate an array to hold the output normals // allocate an array to hold the output normals
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
const float qnan = get_qnan(); const float qnan = get_qnan();
// iterate through all faces and compute per-face normals but store them per-vertex. // iterate through all faces and compute per-face normals but store them per-vertex.
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
const aiFace& face = pMesh->mFaces[a]; const aiFace& face = pMesh->mFaces[a];
if (face.mNumIndices < 3) { if (face.mNumIndices < 3) {
// either a point or a line -> no well-defined normal vector // either a point or a line -> no well-defined normal vector
for (unsigned int i = 0;i < face.mNumIndices;++i) { for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan); pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
} }
continue; continue;
} }
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize(); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
for (unsigned int i = 0;i < face.mNumIndices;++i) { for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;
} }
} }
return true; return true;
} }

View File

@ -1,84 +1,84 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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*/ /** @file Defines a post processing step to compute face normals for all loaded faces*/
#ifndef AI_GENFACENORMALPROCESS_H_INC #ifndef AI_GENFACENORMALPROCESS_H_INC
#define AI_GENFACENORMALPROCESS_H_INC #define AI_GENFACENORMALPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The GenFaceNormalsProcess computes face normals for all faces of all meshes /** The GenFaceNormalsProcess computes face normals for all faces of all meshes
*/ */
class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
{ {
public: public:
GenFaceNormalsProcess(); GenFaceNormalsProcess();
~GenFaceNormalsProcess(); ~GenFaceNormalsProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field. /** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise * @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps. * combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not. * @return true if the process is present in this flag fields, false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
private: private:
bool GenMeshFaceNormals (aiMesh* pcMesh); bool GenMeshFaceNormals (aiMesh* pcMesh);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // !!AI_GENFACENORMALPROCESS_H_INC #endif // !!AI_GENFACENORMALPROCESS_H_INC

View File

@ -1,236 +1,236 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the post processing step to generate face /** @file Implementation of the post processing step to generate face
* normals for all imported faces. * normals for all imported faces.
*/ */
// internal headers // internal headers
#include "GenVertexNormalsProcess.h" #include "GenVertexNormalsProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "Exceptional.h" #include "Exceptional.h"
#include "qnan.h" #include "qnan.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
GenVertexNormalsProcess::GenVertexNormalsProcess() GenVertexNormalsProcess::GenVertexNormalsProcess()
{ {
this->configMaxAngle = AI_DEG_TO_RAD(175.f); this->configMaxAngle = AI_DEG_TO_RAD(175.f);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
GenVertexNormalsProcess::~GenVertexNormalsProcess() GenVertexNormalsProcess::~GenVertexNormalsProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_GenSmoothNormals) != 0; return (pFlags & aiProcess_GenSmoothNormals) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void GenVertexNormalsProcess::SetupProperties(const Importer* pImp) void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
{ {
// Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property // 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 = 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)); configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle,175.0f),0.0f));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void GenVertexNormalsProcess::Execute( aiScene* pScene) void GenVertexNormalsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("GenVertexNormalsProcess begin"); DefaultLogger::get()->debug("GenVertexNormalsProcess begin");
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{ {
if(GenMeshVertexNormals( pScene->mMeshes[a],a)) if(GenMeshVertexNormals( pScene->mMeshes[a],a))
bHas = true; bHas = true;
} }
if (bHas) { if (bHas) {
DefaultLogger::get()->info("GenVertexNormalsProcess finished. " DefaultLogger::get()->info("GenVertexNormalsProcess finished. "
"Vertex normals have been calculated"); "Vertex normals have been calculated");
} }
else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. " else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. "
"Normals are already there"); "Normals are already there");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex) bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
{ {
if (NULL != pMesh->mNormals) if (NULL != pMesh->mNormals)
return false; return false;
// If the mesh consists of lines and/or points but not of // If the mesh consists of lines and/or points but not of
// triangles or higher-order polygons the normal vectors // triangles or higher-order polygons the normal vectors
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
{ {
DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes"); DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
return false; return false;
} }
// Allocate the array to hold the output normals // Allocate the array to hold the output normals
const float qnan = std::numeric_limits<float>::quiet_NaN(); const float qnan = std::numeric_limits<float>::quiet_NaN();
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
// Compute per-face normals but store them per-vertex // Compute per-face normals but store them per-vertex
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{ {
const aiFace& face = pMesh->mFaces[a]; const aiFace& face = pMesh->mFaces[a];
if (face.mNumIndices < 3) if (face.mNumIndices < 3)
{ {
// either a point or a line -> no normal vector // either a point or a line -> no normal vector
for (unsigned int i = 0;i < face.mNumIndices;++i) { for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan); pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
} }
continue; continue;
} }
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1));
for (unsigned int i = 0;i < face.mNumIndices;++i) { for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;
} }
} }
// Set up a SpatialSort to quickly find all vertices close to a given position // 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. // check whether we can reuse the SpatialSort of a previous step.
SpatialSort* vertexFinder = NULL; SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder; SpatialSort _vertexFinder;
float posEpsilon = 1e-5f; float posEpsilon = 1e-5f;
if (shared) { if (shared) {
std::vector<std::pair<SpatialSort,float> >* avf; std::vector<std::pair<SpatialSort,float> >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf); shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf) if (avf)
{ {
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex); std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
vertexFinder = &blubb.first; vertexFinder = &blubb.first;
posEpsilon = blubb.second; posEpsilon = blubb.second;
} }
} }
if (!vertexFinder) { if (!vertexFinder) {
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder; vertexFinder = &_vertexFinder;
posEpsilon = ComputePositionEpsilon(pMesh); posEpsilon = ComputePositionEpsilon(pMesh);
} }
std::vector<unsigned int> verticesFound; std::vector<unsigned int> verticesFound;
aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices]; aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
if (configMaxAngle >= AI_DEG_TO_RAD( 175.f )) { if (configMaxAngle >= AI_DEG_TO_RAD( 175.f )) {
// There is no angle limit. Thus all vertices with positions close // There is no angle limit. Thus all vertices with positions close
// to each other will receive the same vertex normal. This allows us // to each other will receive the same vertex normal. This allows us
// to optimize the whole algorithm a little bit ... // to optimize the whole algorithm a little bit ...
std::vector<bool> abHad(pMesh->mNumVertices,false); std::vector<bool> abHad(pMesh->mNumVertices,false);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
if (abHad[i]) { if (abHad[i]) {
continue; continue;
} }
// Get all vertices that share this one ... // Get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound); vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
aiVector3D pcNor; aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a) { for (unsigned int a = 0; a < verticesFound.size(); ++a) {
const aiVector3D& v = pMesh->mNormals[verticesFound[a]]; const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
if (is_not_qnan(v.x))pcNor += v; if (is_not_qnan(v.x))pcNor += v;
} }
pcNor.Normalize(); pcNor.Normalize();
// Write the smoothed normal back to all affected normals // Write the smoothed normal back to all affected normals
for (unsigned int a = 0; a < verticesFound.size(); ++a) for (unsigned int a = 0; a < verticesFound.size(); ++a)
{ {
unsigned int vidx = verticesFound[a]; unsigned int vidx = verticesFound[a];
pcNew[vidx] = pcNor; pcNew[vidx] = pcNor;
abHad[vidx] = true; abHad[vidx] = true;
} }
} }
} }
// Slower code path if a smooth angle is set. There are many ways to achieve // Slower code path if a smooth angle is set. There are many ways to achieve
// the effect, this one is the most straightforward one. // the effect, this one is the most straightforward one.
else { else {
const float fLimit = std::cos(configMaxAngle); const float fLimit = std::cos(configMaxAngle);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
// Get all vertices that share this one ... // Get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound); vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
aiVector3D vr = pMesh->mNormals[i]; aiVector3D vr = pMesh->mNormals[i];
float vrlen = vr.Length(); float vrlen = vr.Length();
aiVector3D pcNor; aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a) { for (unsigned int a = 0; a < verticesFound.size(); ++a) {
aiVector3D v = pMesh->mNormals[verticesFound[a]]; aiVector3D v = pMesh->mNormals[verticesFound[a]];
// check whether the angle between the two normals is not too large // 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 // HACK: if v.x is qnan the dot product will become qnan, too
// therefore the comparison against fLimit should be false // therefore the comparison against fLimit should be false
// in every case. // in every case.
if (v * vr >= fLimit * vrlen * v.Length()) if (v * vr >= fLimit * vrlen * v.Length())
pcNor += v; pcNor += v;
} }
pcNew[i] = pcNor.Normalize(); pcNew[i] = pcNor.Normalize();
} }
} }
delete[] pMesh->mNormals; delete[] pMesh->mNormals;
pMesh->mNormals = pcNew; pMesh->mNormals = pcNew;
return true; return true;
} }

View File

@ -1,113 +1,113 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to compute vertex normals /** @file Defines a post processing step to compute vertex normals
for all loaded vertizes */ for all loaded vertizes */
#ifndef AI_GENVERTEXNORMALPROCESS_H_INC #ifndef AI_GENVERTEXNORMALPROCESS_H_INC
#define AI_GENVERTEXNORMALPROCESS_H_INC #define AI_GENVERTEXNORMALPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
class GenNormalsTest; class GenNormalsTest;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The GenFaceNormalsProcess computes vertex normals for all vertizes /** The GenFaceNormalsProcess computes vertex normals for all vertizes
*/ */
class ASSIMP_API GenVertexNormalsProcess : public BaseProcess class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
{ {
public: public:
GenVertexNormalsProcess(); GenVertexNormalsProcess();
~GenVertexNormalsProcess(); ~GenVertexNormalsProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. * @param pFlags The processing flags the importer was called with.
* A bitwise combination of #aiPostProcessSteps. * A bitwise combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, * @return true if the process is present in this flag fields,
* false if not. * false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ExecuteOnScene(). /** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration * The function is a request to the process to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
// setter for configMaxAngle // setter for configMaxAngle
inline void SetMaxSmoothAngle(float f) inline void SetMaxSmoothAngle(float f)
{ {
configMaxAngle =f; configMaxAngle =f;
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes normals for a specific mesh /** Computes normals for a specific mesh
* @param pcMesh Mesh * @param pcMesh Mesh
* @param meshIndex Index of the mesh * @param meshIndex Index of the mesh
* @return true if vertex normals have been computed * @return true if vertex normals have been computed
*/ */
bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex); bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
private: private:
/** Configuration option: maximum smoothing angle, in radians*/ /** Configuration option: maximum smoothing angle, in radians*/
float configMaxAngle; float configMaxAngle;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC #endif // !!AI_GENVERTEXNORMALPROCESS_H_INC

View File

@ -1,125 +1,125 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED #ifndef AI_GENERIC_PROPERTY_H_INCLUDED
#define AI_GENERIC_PROPERTY_H_INCLUDED #define AI_GENERIC_PROPERTY_H_INCLUDED
#include "./../include/assimp/Importer.hpp" #include "./../include/assimp/Importer.hpp"
#include "./../include/assimp/ai_assert.h" #include "./../include/assimp/ai_assert.h"
#include "Hash.h" #include "Hash.h"
#include <map> #include <map>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline bool SetGenericProperty(std::map< unsigned int, T >& list, inline bool SetGenericProperty(std::map< unsigned int, T >& list,
const char* szName, const T& value) const char* szName, const T& value)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
const uint32_t hash = SuperFastHash(szName); const uint32_t hash = SuperFastHash(szName);
typename std::map<unsigned int, T>::iterator it = list.find(hash); typename std::map<unsigned int, T>::iterator it = list.find(hash);
if (it == list.end()) { if (it == list.end()) {
list.insert(std::pair<unsigned int, T>( hash, value )); list.insert(std::pair<unsigned int, T>( hash, value ));
return false; return false;
} }
(*it).second = value; (*it).second = value;
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline const T& GetGenericProperty(const std::map< unsigned int, T >& list, inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
const char* szName, const T& errorReturn) const char* szName, const T& errorReturn)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
const uint32_t hash = SuperFastHash(szName); const uint32_t hash = SuperFastHash(szName);
typename std::map<unsigned int, T>::const_iterator it = list.find(hash); typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
if (it == list.end()) if (it == list.end())
return errorReturn; return errorReturn;
return (*it).second; return (*it).second;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Special version for pointer types - they will be deleted when replaced with another value // Special version for pointer types - they will be deleted when replaced with another value
// passing NULL removes the whole property // passing NULL removes the whole property
template <class T> template <class T>
inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list, inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
const char* szName, T* value, bool* bWasExisting = NULL) const char* szName, T* value, bool* bWasExisting = NULL)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
const uint32_t hash = SuperFastHash(szName); const uint32_t hash = SuperFastHash(szName);
typename std::map<unsigned int, T*>::iterator it = list.find(hash); typename std::map<unsigned int, T*>::iterator it = list.find(hash);
if (it == list.end()) { if (it == list.end()) {
if (bWasExisting) if (bWasExisting)
*bWasExisting = false; *bWasExisting = false;
list.insert(std::pair<unsigned int,T*>( hash, value )); list.insert(std::pair<unsigned int,T*>( hash, value ));
return; return;
} }
if ((*it).second != value) { if ((*it).second != value) {
delete (*it).second; delete (*it).second;
(*it).second = value; (*it).second = value;
} }
if (!value) { if (!value) {
list.erase(it); list.erase(it);
} }
if (bWasExisting) if (bWasExisting)
*bWasExisting = true; *bWasExisting = true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list, inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
const char* szName) const char* szName)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
const uint32_t hash = SuperFastHash(szName); const uint32_t hash = SuperFastHash(szName);
typename std::map<unsigned int, T>::const_iterator it = list.find(hash); typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
if (it == list.end()) return false; if (it == list.end()) return false;
return true; return true;
} }
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED #endif // !! AI_GENERIC_PROPERTY_H_INCLUDED

View File

@ -1,135 +1,135 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
//! //!
//! @file Data structures for the 3D Game Studio Heightmap format (HMP) //! @file Data structures for the 3D Game Studio Heightmap format (HMP)
//! //!
namespace Assimp { namespace Assimp {
namespace HMP { namespace HMP {
#include "./../include/assimp/Compiler/pushpack1.h" #include "./../include/assimp/Compiler/pushpack1.h"
#include <stdint.h> #include <stdint.h>
// to make it easier for us, we test the magic word against both "endianesses" // 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_BE_4 AI_MAKE_MAGIC("HMP4")
#define AI_HMP_MAGIC_NUMBER_LE_4 AI_MAKE_MAGIC("4PMH") #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_BE_5 AI_MAKE_MAGIC("HMP5")
#define AI_HMP_MAGIC_NUMBER_LE_5 AI_MAKE_MAGIC("5PMH") #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_BE_7 AI_MAKE_MAGIC("HMP7")
#define AI_HMP_MAGIC_NUMBER_LE_7 AI_MAKE_MAGIC("7PMH") #define AI_HMP_MAGIC_NUMBER_LE_7 AI_MAKE_MAGIC("7PMH")
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for the header of a HMP5 file. /** Data structure for the header of a HMP5 file.
* This is also used by HMP4 and HMP7, but with modifications * This is also used by HMP4 and HMP7, but with modifications
*/ */
struct Header_HMP5 struct Header_HMP5
{ {
int8_t ident[4]; // "HMP5" int8_t ident[4]; // "HMP5"
int32_t version; int32_t version;
// ignored // ignored
float scale[3]; float scale[3];
float scale_origin[3]; float scale_origin[3];
float boundingradius; float boundingradius;
//! Size of one triangle in x direction //! Size of one triangle in x direction
float ftrisize_x; float ftrisize_x;
//! Size of one triangle in y direction //! Size of one triangle in y direction
float ftrisize_y; float ftrisize_y;
//! Number of vertices in x direction //! Number of vertices in x direction
float fnumverts_x; float fnumverts_x;
//! Number of skins in the file //! Number of skins in the file
int32_t numskins; int32_t numskins;
// can ignore this? // can ignore this?
int32_t skinwidth; int32_t skinwidth;
int32_t skinheight; int32_t skinheight;
//!Number of vertices in the file //!Number of vertices in the file
int32_t numverts; int32_t numverts;
// ignored and zero // ignored and zero
int32_t numtris; int32_t numtris;
//! only one supported ... //! only one supported ...
int32_t numframes; int32_t numframes;
//! Always 0 ... //! Always 0 ...
int32_t num_stverts; int32_t num_stverts;
int32_t flags; int32_t flags;
float size; float size;
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a terrain vertex in a HMP4 file /** Data structure for a terrain vertex in a HMP4 file
*/ */
struct Vertex_HMP4 struct Vertex_HMP4
{ {
uint16_t p_pos[3]; uint16_t p_pos[3];
uint8_t normals162index; uint8_t normals162index;
uint8_t pad; uint8_t pad;
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a terrain vertex in a HMP5 file /** Data structure for a terrain vertex in a HMP5 file
*/ */
struct Vertex_HMP5 struct Vertex_HMP5
{ {
uint16_t z; uint16_t z;
uint8_t normals162index; uint8_t normals162index;
uint8_t pad; uint8_t pad;
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a terrain vertex in a HMP7 file /** Data structure for a terrain vertex in a HMP7 file
*/ */
struct Vertex_HMP7 struct Vertex_HMP7
{ {
uint16_t z; uint16_t z;
int8_t normal_x,normal_y; int8_t normal_x,normal_y;
} PACK_STRUCT; } PACK_STRUCT;
#include "./../include/assimp/Compiler/poppack1.h" #include "./../include/assimp/Compiler/poppack1.h"
} //! namespace HMP } //! namespace HMP
} //! namespace Assimp } //! namespace Assimp

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +1,155 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file HMPLoader.h /** @file HMPLoader.h
* @brief Declaration of the HMP importer class * @brief Declaration of the HMP importer class
*/ */
#ifndef AI_HMPLOADER_H_INCLUDED #ifndef AI_HMPLOADER_H_INCLUDED
#define AI_HMPLOADER_H_INCLUDED #define AI_HMPLOADER_H_INCLUDED
// public ASSIMP headers // public ASSIMP headers
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "../include/assimp/texture.h" #include "../include/assimp/texture.h"
#include "../include/assimp/material.h" #include "../include/assimp/material.h"
// internal headers // internal headers
#include "BaseImporter.h" #include "BaseImporter.h"
#include "MDLLoader.h" #include "MDLLoader.h"
#include "HMPFileData.h" #include "HMPFileData.h"
namespace Assimp { namespace Assimp {
using namespace HMP; using namespace HMP;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Used to load 3D GameStudio HMP files (terrains) /** Used to load 3D GameStudio HMP files (terrains)
*/ */
class HMPImporter : public MDLImporter class HMPImporter : public MDLImporter
{ {
public: public:
HMPImporter(); HMPImporter();
~HMPImporter(); ~HMPImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Import a HMP4 file /** Import a HMP4 file
*/ */
void InternReadFile_HMP4( ); void InternReadFile_HMP4( );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Import a HMP5 file /** Import a HMP5 file
*/ */
void InternReadFile_HMP5( ); void InternReadFile_HMP5( );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Import a HMP7 file /** Import a HMP7 file
*/ */
void InternReadFile_HMP7( ); void InternReadFile_HMP7( );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Validate a HMP 5,4,7 file header /** Validate a HMP 5,4,7 file header
*/ */
void ValidateHeader_HMP457( ); void ValidateHeader_HMP457( );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Try to load one material from the file, if this fails create /** Try to load one material from the file, if this fails create
* a default material * a default material
*/ */
void CreateMaterial(const unsigned char* szCurrent, void CreateMaterial(const unsigned char* szCurrent,
const unsigned char** szCurrentOut); const unsigned char** szCurrentOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build a list of output faces and vertices. The function /** Build a list of output faces and vertices. The function
* triangulates the height map read from the file * triangulates the height map read from the file
* \param width Width of the height field * \param width Width of the height field
* \param width Height of the height field * \param width Height of the height field
*/ */
void CreateOutputFaceList(unsigned int width,unsigned int height); void CreateOutputFaceList(unsigned int width,unsigned int height);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate planar texture coordinates for a terrain /** Generate planar texture coordinates for a terrain
* \param width Width of the terrain, in vertices * \param width Width of the terrain, in vertices
* \param height Height of the terrain, in vertices * \param height Height of the terrain, in vertices
*/ */
void GenerateTextureCoords(const unsigned int width, void GenerateTextureCoords(const unsigned int width,
const unsigned int height); const unsigned int height);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read the first skin from the file and skip all others ... /** Read the first skin from the file and skip all others ...
* \param iNumSkins Number of skins in the file * \param iNumSkins Number of skins in the file
* \param szCursor Position of the first skin (offset 84) * \param szCursor Position of the first skin (offset 84)
*/ */
void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor, void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
const unsigned char** szCursorOut); const unsigned char** szCursorOut);
private: private:
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_HMPIMPORTER_H_INC #endif // AI_HMPIMPORTER_H_INC

View File

@ -1,149 +1,149 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
// //
//! @file Definition of in-memory structures for the HL2 MDL file format //! @file Definition of in-memory structures for the HL2 MDL file format
// and for the HalfLife text format (SMD) // and for the HalfLife text format (SMD)
// //
// The specification has been taken from various sources on the internet. // The specification has been taken from various sources on the internet.
#ifndef AI_MDLFILEHELPER2_H_INC #ifndef AI_MDLFILEHELPER2_H_INC
#define AI_MDLFILEHELPER2_H_INC #define AI_MDLFILEHELPER2_H_INC
#include "MDLFileData.h" #include "MDLFileData.h"
#include "./../include/assimp/Compiler/pushpack1.h" #include "./../include/assimp/Compiler/pushpack1.h"
namespace Assimp { namespace Assimp {
namespace MDL { namespace MDL {
// magic bytes used in Half Life 2 MDL models // 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_BE_HL2a AI_MAKE_MAGIC("IDST")
#define AI_MDL_MAGIC_NUMBER_LE_HL2a AI_MAKE_MAGIC("TSDI") #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_BE_HL2b AI_MAKE_MAGIC("IDSQ")
#define AI_MDL_MAGIC_NUMBER_LE_HL2b AI_MAKE_MAGIC("QSDI") #define AI_MDL_MAGIC_NUMBER_LE_HL2b AI_MAKE_MAGIC("QSDI")
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \struct Header_HL2 /** \struct Header_HL2
* \brief Data structure for the HL2 main header * \brief Data structure for the HL2 main header
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
struct Header_HL2 struct Header_HL2
{ {
//! magic number: "IDST"/"IDSQ" //! magic number: "IDST"/"IDSQ"
char ident[4]; char ident[4];
//! Version number //! Version number
int32_t version; int32_t version;
//! Original file name in pak ? //! Original file name in pak ?
char name[64]; char name[64];
//! Length of file name/length of file? //! Length of file name/length of file?
int32_t length; int32_t length;
//! For viewer, ignored //! For viewer, ignored
aiVector3D eyeposition; aiVector3D eyeposition;
aiVector3D min; aiVector3D min;
aiVector3D max; aiVector3D max;
//! AABB of the model //! AABB of the model
aiVector3D bbmin; aiVector3D bbmin;
aiVector3D bbmax; aiVector3D bbmax;
// File flags // File flags
int32_t flags; int32_t flags;
//! NUmber of bones contained in the file //! NUmber of bones contained in the file
int32_t numbones; int32_t numbones;
int32_t boneindex; int32_t boneindex;
//! Number of bone controllers for bone animation //! Number of bone controllers for bone animation
int32_t numbonecontrollers; int32_t numbonecontrollers;
int32_t bonecontrollerindex; int32_t bonecontrollerindex;
//! More bounding boxes ... //! More bounding boxes ...
int32_t numhitboxes; int32_t numhitboxes;
int32_t hitboxindex; int32_t hitboxindex;
//! Animation sequences in the file //! Animation sequences in the file
int32_t numseq; int32_t numseq;
int32_t seqindex; int32_t seqindex;
//! Loaded sequences. Ignored //! Loaded sequences. Ignored
int32_t numseqgroups; int32_t numseqgroups;
int32_t seqgroupindex; int32_t seqgroupindex;
//! Raw texture data //! Raw texture data
int32_t numtextures; int32_t numtextures;
int32_t textureindex; int32_t textureindex;
int32_t texturedataindex; int32_t texturedataindex;
//! Number of skins (=textures?) //! Number of skins (=textures?)
int32_t numskinref; int32_t numskinref;
int32_t numskinfamilies; int32_t numskinfamilies;
int32_t skinindex; int32_t skinindex;
//! Number of parts //! Number of parts
int32_t numbodyparts; int32_t numbodyparts;
int32_t bodypartindex; int32_t bodypartindex;
//! attachable points for gameplay and physics //! attachable points for gameplay and physics
int32_t numattachments; int32_t numattachments;
int32_t attachmentindex; int32_t attachmentindex;
//! Table of sound effects associated with the model //! Table of sound effects associated with the model
int32_t soundtable; int32_t soundtable;
int32_t soundindex; int32_t soundindex;
int32_t soundgroups; int32_t soundgroups;
int32_t soundgroupindex; int32_t soundgroupindex;
//! Number of animation transitions //! Number of animation transitions
int32_t numtransitions; int32_t numtransitions;
int32_t transitionindex; int32_t transitionindex;
} PACK_STRUCT; } PACK_STRUCT;
#include "./../include/assimp/Compiler/poppack1.h" #include "./../include/assimp/Compiler/poppack1.h"
} }
} // end namespaces } // end namespaces
#endif // ! AI_MDLFILEHELPER2_H_INC #endif // ! AI_MDLFILEHELPER2_H_INC

View File

@ -1,116 +1,116 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef AI_HASH_H_INCLUDED #ifndef AI_HASH_H_INCLUDED
#define AI_HASH_H_INCLUDED #define AI_HASH_H_INCLUDED
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Hashing function taken from // Hashing function taken from
// http://www.azillionmonkeys.com/qed/hash.html // http://www.azillionmonkeys.com/qed/hash.html
// (incremental version) // (incremental version)
// //
// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that // This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that
// Assimp's license is considered compatible with Pauls's derivative license as specified // Assimp's license is considered compatible with Pauls's derivative license as specified
// on his web page. // on his web page.
// //
// (stdint.h should have been been included here) // (stdint.h should have been been included here)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#undef get16bits #undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d))) #define get16bits(d) (*((const uint16_t *) (d)))
#endif #endif
#if !defined (get16bits) #if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) ) +(uint32_t)(((const uint8_t *)(d))[0]) )
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) {
uint32_t tmp; uint32_t tmp;
int rem; int rem;
if (!data) return 0; if (!data) return 0;
if (!len)len = (uint32_t)::strlen(data); if (!len)len = (uint32_t)::strlen(data);
rem = len & 3; rem = len & 3;
len >>= 2; len >>= 2;
/* Main loop */ /* Main loop */
for (;len > 0; len--) { for (;len > 0; len--) {
hash += get16bits (data); hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash; tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp; hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t); data += 2*sizeof (uint16_t);
hash += hash >> 11; hash += hash >> 11;
} }
/* Handle end cases */ /* Handle end cases */
switch (rem) { switch (rem) {
case 3: hash += get16bits (data); case 3: hash += get16bits (data);
hash ^= hash << 16; hash ^= hash << 16;
hash ^= data[sizeof (uint16_t)] << 18; hash ^= data[sizeof (uint16_t)] << 18;
hash += hash >> 11; hash += hash >> 11;
break; break;
case 2: hash += get16bits (data); case 2: hash += get16bits (data);
hash ^= hash << 11; hash ^= hash << 11;
hash += hash >> 17; hash += hash >> 17;
break; break;
case 1: hash += *data; case 1: hash += *data;
hash ^= hash << 10; hash ^= hash << 10;
hash += hash >> 1; hash += hash >> 1;
} }
/* Force "avalanching" of final 127 bits */ /* Force "avalanching" of final 127 bits */
hash ^= hash << 3; hash ^= hash << 3;
hash += hash >> 5; hash += hash >> 5;
hash ^= hash << 4; hash ^= hash << 4;
hash += hash >> 17; hash += hash >> 17;
hash ^= hash << 25; hash ^= hash << 25;
hash += hash >> 6; hash += hash >> 6;
return hash; return hash;
} }
#endif // !! AI_HASH_H_INCLUDED #endif // !! AI_HASH_H_INCLUDED

View File

@ -298,12 +298,12 @@ bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const
{ {
// calculate closest point to each end on the segment, clamp that point to the segment's length, then check // calculate closest point to each end on the segment, clamp that point to the segment's length, then check
// distance to that point. This approach is like testing if e0 is inside a capped cylinder. // distance to that point. This approach is like testing if e0 is inside a capped cylinder.
IfcFloat et0 = (b.x*(e0.x - b0.x) + b.y*(e0.y - b0.y)) * b_sqlen_inv; IfcFloat et0 = (b.x*(e0.x - b0.x) + b.y*(e0.y - b0.y)) * b_sqlen_inv;
IfcVector3 closestPosToE0OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et0)) * b; IfcVector3 closestPosToE0OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et0)) * b;
startsAtSegment = (closestPosToE0OnBoundary - IfcVector3(e0.x, e0.y, 0.0)).SquareLength() < 1e-12; startsAtSegment = (closestPosToE0OnBoundary - IfcVector3(e0.x, e0.y, 0.0)).SquareLength() < 1e-12;
IfcFloat et1 = (b.x*(e1.x - b0.x) + b.y*(e1.y - b0.y)) * b_sqlen_inv; IfcFloat et1 = (b.x*(e1.x - b0.x) + b.y*(e1.y - b0.y)) * b_sqlen_inv;
IfcVector3 closestPosToE1OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et1)) * b; IfcVector3 closestPosToE1OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et1)) * b;
endsAtSegment = (closestPosToE1OnBoundary - IfcVector3(e1.x, e1.y, 0.0)).SquareLength() < 1e-12; endsAtSegment = (closestPosToE1OnBoundary - IfcVector3(e1.x, e1.y, 0.0)).SquareLength() < 1e-12;
} }
// Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments // Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,132 +1,132 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFC.h /** @file IFC.h
* @brief Declaration of the Industry Foundation Classes (IFC) loader main class * @brief Declaration of the Industry Foundation Classes (IFC) loader main class
*/ */
#ifndef INCLUDED_AI_IFC_LOADER_H #ifndef INCLUDED_AI_IFC_LOADER_H
#define INCLUDED_AI_IFC_LOADER_H #define INCLUDED_AI_IFC_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
#include "LogAux.h" #include "LogAux.h"
namespace Assimp { namespace Assimp {
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
namespace STEP { namespace STEP {
class DB; class DB;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Load the IFC format, which is an open specification to describe building and construction /** Load the IFC format, which is an open specification to describe building and construction
industry data. industry data.
See http://en.wikipedia.org/wiki/Industry_Foundation_Classes See http://en.wikipedia.org/wiki/Industry_Foundation_Classes
*/ */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter> class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter>
{ {
public: public:
IFCImporter(); IFCImporter();
~IFCImporter(); ~IFCImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, bool CanRead( const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, void InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
private: private:
public: public:
// loader settings, publicly accessible via their corresponding AI_CONFIG constants // loader settings, publicly accessible via their corresponding AI_CONFIG constants
struct Settings struct Settings
{ {
Settings() Settings()
: skipSpaceRepresentations() : skipSpaceRepresentations()
, skipCurveRepresentations() , skipCurveRepresentations()
, useCustomTriangulation() , useCustomTriangulation()
, skipAnnotations() , skipAnnotations()
, conicSamplingAngle(10.f) , conicSamplingAngle(10.f)
{} {}
bool skipSpaceRepresentations; bool skipSpaceRepresentations;
bool skipCurveRepresentations; bool skipCurveRepresentations;
bool useCustomTriangulation; bool useCustomTriangulation;
bool skipAnnotations; bool skipAnnotations;
float conicSamplingAngle; float conicSamplingAngle;
}; };
private: private:
Settings settings; Settings settings;
}; // !class IFCImporter }; // !class IFCImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // !INCLUDED_AI_IFC_LOADER_H #endif // !INCLUDED_AI_IFC_LOADER_H

View File

@ -1,206 +1,206 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCMaterial.cpp /** @file IFCMaterial.cpp
* @brief Implementation of conversion routines to convert IFC materials to aiMaterial * @brief Implementation of conversion routines to convert IFC materials to aiMaterial
*/ */
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h" #include "IFCUtil.h"
#include <limits> #include <limits>
#include "../include/assimp/material.h" #include "../include/assimp/material.h"
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int ConvertShadingMode(const std::string& name) int ConvertShadingMode(const std::string& name)
{ {
if (name == "BLINN") { if (name == "BLINN") {
return aiShadingMode_Blinn; return aiShadingMode_Blinn;
} }
else if (name == "FLAT" || name == "NOTDEFINED") { else if (name == "FLAT" || name == "NOTDEFINED") {
return aiShadingMode_NoShading; return aiShadingMode_NoShading;
} }
else if (name == "PHONG") { else if (name == "PHONG") {
return aiShadingMode_Phong; return aiShadingMode_Phong;
} }
IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead"); IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead");
return aiShadingMode_Phong; return aiShadingMode_Phong;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionData& conv) void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionData& conv)
{ {
aiString name; aiString name;
name.Set((surf->Name? surf->Name.Get() : "IfcSurfaceStyle_Unnamed")); name.Set((surf->Name? surf->Name.Get() : "IfcSurfaceStyle_Unnamed"));
mat->AddProperty(&name,AI_MATKEY_NAME); mat->AddProperty(&name,AI_MATKEY_NAME);
// now see which kinds of surface information are present // now see which kinds of surface information are present
BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) { BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) {
if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) { if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) {
aiColor4D col_base,col; aiColor4D col_base,col;
ConvertColor(col_base, shade->SurfaceColour); ConvertColor(col_base, shade->SurfaceColour);
mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE);
if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) { if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) {
if (ren->Transparency) { if (ren->Transparency) {
const float t = 1.f-static_cast<float>(ren->Transparency.Get()); const float t = 1.f-static_cast<float>(ren->Transparency.Get());
mat->AddProperty(&t,1, AI_MATKEY_OPACITY); mat->AddProperty(&t,1, AI_MATKEY_OPACITY);
} }
if (ren->DiffuseColour) { if (ren->DiffuseColour) {
ConvertColor(col, *ren->DiffuseColour.Get(),conv,&col_base); ConvertColor(col, *ren->DiffuseColour.Get(),conv,&col_base);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
} }
if (ren->SpecularColour) { if (ren->SpecularColour) {
ConvertColor(col, *ren->SpecularColour.Get(),conv,&col_base); ConvertColor(col, *ren->SpecularColour.Get(),conv,&col_base);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR); mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR);
} }
if (ren->TransmissionColour) { if (ren->TransmissionColour) {
ConvertColor(col, *ren->TransmissionColour.Get(),conv,&col_base); ConvertColor(col, *ren->TransmissionColour.Get(),conv,&col_base);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_TRANSPARENT); mat->AddProperty(&col,1, AI_MATKEY_COLOR_TRANSPARENT);
} }
if (ren->ReflectionColour) { if (ren->ReflectionColour) {
ConvertColor(col, *ren->ReflectionColour.Get(),conv,&col_base); ConvertColor(col, *ren->ReflectionColour.Get(),conv,&col_base);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE); mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE);
} }
const int shading = (ren->SpecularHighlight && ren->SpecularColour)?ConvertShadingMode(ren->ReflectanceMethod):static_cast<int>(aiShadingMode_Gouraud); const int shading = (ren->SpecularHighlight && ren->SpecularColour)?ConvertShadingMode(ren->ReflectanceMethod):static_cast<int>(aiShadingMode_Gouraud);
mat->AddProperty(&shading,1, AI_MATKEY_SHADING_MODEL); mat->AddProperty(&shading,1, AI_MATKEY_SHADING_MODEL);
if (ren->SpecularHighlight) { if (ren->SpecularHighlight) {
if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) { if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) {
// at this point we don't distinguish between the two distinct ways of // at this point we don't distinguish between the two distinct ways of
// specifying highlight intensities. leave this to the user. // specifying highlight intensities. leave this to the user.
const float e = static_cast<float>(*rt); const float e = static_cast<float>(*rt);
mat->AddProperty(&e,1,AI_MATKEY_SHININESS); mat->AddProperty(&e,1,AI_MATKEY_SHININESS);
} }
else { else {
IFCImporter::LogWarn("unexpected type error, SpecularHighlight should be a REAL"); IFCImporter::LogWarn("unexpected type error, SpecularHighlight should be a REAL");
} }
} }
} }
} /* } /*
else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) { else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) {
// XXX // XXX
} */ } */
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat) unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat)
{ {
STEP::DB::RefMapRange range = conv.db.GetRefs().equal_range(id); STEP::DB::RefMapRange range = conv.db.GetRefs().equal_range(id);
for(;range.first != range.second; ++range.first) { for(;range.first != range.second; ++range.first) {
if(const IFC::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::IfcStyledItem>()) { if(const IFC::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::IfcStyledItem>()) {
BOOST_FOREACH(const IFC::IfcPresentationStyleAssignment& as, styled->Styles) { BOOST_FOREACH(const IFC::IfcPresentationStyleAssignment& as, styled->Styles) {
BOOST_FOREACH(boost::shared_ptr<const IFC::IfcPresentationStyleSelect> sel, as.Styles) { BOOST_FOREACH(boost::shared_ptr<const IFC::IfcPresentationStyleSelect> sel, as.Styles) {
if( const IFC::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::IfcSurfaceStyle>(conv.db) ) { if( const IFC::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::IfcSurfaceStyle>(conv.db) ) {
// try to satisfy from cache // try to satisfy from cache
ConversionData::MaterialCache::iterator mit = conv.cached_materials.find(surf); ConversionData::MaterialCache::iterator mit = conv.cached_materials.find(surf);
if( mit != conv.cached_materials.end() ) if( mit != conv.cached_materials.end() )
return mit->second; return mit->second;
// not found, create new material // not found, create new material
const std::string side = static_cast<std::string>(surf->Side); const std::string side = static_cast<std::string>(surf->Side);
if( side != "BOTH" ) { if( side != "BOTH" ) {
IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side); IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side);
} }
std::auto_ptr<aiMaterial> mat(new aiMaterial()); std::auto_ptr<aiMaterial> mat(new aiMaterial());
FillMaterial(mat.get(), surf, conv); FillMaterial(mat.get(), surf, conv);
conv.materials.push_back(mat.release()); conv.materials.push_back(mat.release());
unsigned int matindex = conv.materials.size() - 1; unsigned int matindex = conv.materials.size() - 1;
conv.cached_materials[surf] = matindex; conv.cached_materials[surf] = matindex;
return matindex; return matindex;
} }
} }
} }
} }
} }
// no local material defined. If there's global one, use that instead // no local material defined. If there's global one, use that instead
if( prevMatId != std::numeric_limits<uint32_t>::max() ) if( prevMatId != std::numeric_limits<uint32_t>::max() )
return prevMatId; return prevMatId;
// we're still here - create an default material if required, or simply fail otherwise // we're still here - create an default material if required, or simply fail otherwise
if( !forceDefaultMat ) if( !forceDefaultMat )
return std::numeric_limits<uint32_t>::max(); return std::numeric_limits<uint32_t>::max();
aiString name; aiString name;
name.Set("<IFCDefault>"); name.Set("<IFCDefault>");
// ConvertColorToString( color, name); // ConvertColorToString( color, name);
// look if there's already a default material with this base color // look if there's already a default material with this base color
for( size_t a = 0; a < conv.materials.size(); ++a ) for( size_t a = 0; a < conv.materials.size(); ++a )
{ {
aiString mname; aiString mname;
conv.materials[a]->Get(AI_MATKEY_NAME, mname); conv.materials[a]->Get(AI_MATKEY_NAME, mname);
if( name == mname ) if( name == mname )
return (unsigned int)a; return (unsigned int)a;
} }
// we're here, yet - no default material with suitable color available. Generate one // we're here, yet - no default material with suitable color available. Generate one
std::auto_ptr<aiMaterial> mat(new aiMaterial()); std::auto_ptr<aiMaterial> mat(new aiMaterial());
mat->AddProperty(&name,AI_MATKEY_NAME); mat->AddProperty(&name,AI_MATKEY_NAME);
const aiColor4D col = aiColor4D( 0.6f, 0.6f, 0.6f, 1.0f); // aiColor4D( color.r, color.g, color.b, 1.0f); const aiColor4D col = aiColor4D( 0.6f, 0.6f, 0.6f, 1.0f); // aiColor4D( color.r, color.g, color.b, 1.0f);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
conv.materials.push_back(mat.release()); conv.materials.push_back(mat.release());
return (unsigned int) conv.materials.size() - 1; return (unsigned int) conv.materials.size() - 1;
} }
} // ! IFC } // ! IFC
} // ! Assimp } // ! Assimp
#endif #endif

View File

@ -1,189 +1,189 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFCProfile.cpp /** @file IFCProfile.cpp
* @brief Read profile and curves entities from IFC files * @brief Read profile and curves entities from IFC files
*/ */
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h" #include "IFCUtil.h"
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/) void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
{ {
// this won't produce a valid mesh, it just spits out a list of vertices // this won't produce a valid mesh, it just spits out a list of vertices
IfcVector3 t; IfcVector3 t;
BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) { BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) {
ConvertCartesianPoint(t,cp); ConvertCartesianPoint(t,cp);
meshout.verts.push_back(t); meshout.verts.push_back(t);
} }
meshout.vertcnt.push_back(meshout.verts.size()); meshout.vertcnt.push_back(meshout.verts.size());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv) bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv)
{ {
boost::scoped_ptr<const Curve> cv(Curve::Convert(curve,conv)); boost::scoped_ptr<const Curve> cv(Curve::Convert(curve,conv));
if (!cv) { if (!cv) {
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
return false; return false;
} }
// we must have a bounded curve at this point // we must have a bounded curve at this point
if (const BoundedCurve* bc = dynamic_cast<const BoundedCurve*>(cv.get())) { if (const BoundedCurve* bc = dynamic_cast<const BoundedCurve*>(cv.get())) {
try { try {
bc->SampleDiscrete(meshout); bc->SampleDiscrete(meshout);
} }
catch(const CurveError& cv) { catch(const CurveError& cv) {
IFCImporter::LogError(cv.s+ " (error occurred while processing curve)"); IFCImporter::LogError(cv.s+ " (error occurred while processing curve)");
return false; return false;
} }
meshout.vertcnt.push_back(meshout.verts.size()); meshout.vertcnt.push_back(meshout.verts.size());
return true; return true;
} }
IFCImporter::LogError("cannot use unbounded curve as profile"); IFCImporter::LogError("cannot use unbounded curve as profile");
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
{ {
ProcessCurve(def.OuterCurve,meshout,conv); ProcessCurve(def.OuterCurve,meshout,conv);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
{ {
ProcessCurve(def.Curve,meshout,conv); ProcessCurve(def.Curve,meshout,conv);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/) void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/)
{ {
if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) { if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
meshout.verts.reserve(meshout.verts.size()+4); meshout.verts.reserve(meshout.verts.size()+4);
meshout.verts.push_back( IfcVector3( x, y, 0.f )); meshout.verts.push_back( IfcVector3( x, y, 0.f ));
meshout.verts.push_back( IfcVector3(-x, y, 0.f )); meshout.verts.push_back( IfcVector3(-x, y, 0.f ));
meshout.verts.push_back( IfcVector3(-x,-y, 0.f )); meshout.verts.push_back( IfcVector3(-x,-y, 0.f ));
meshout.verts.push_back( IfcVector3( x,-y, 0.f )); meshout.verts.push_back( IfcVector3( x,-y, 0.f ));
meshout.vertcnt.push_back(4); meshout.vertcnt.push_back(4);
} }
else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) { else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
if(def.ToPtr<IfcCircleHollowProfileDef>()) { if(def.ToPtr<IfcCircleHollowProfileDef>()) {
// TODO // TODO
} }
const size_t segments = 32; const size_t segments = 32;
const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius; const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
meshout.verts.reserve(segments); meshout.verts.reserve(segments);
IfcFloat angle = 0.f; IfcFloat angle = 0.f;
for(size_t i = 0; i < segments; ++i, angle += delta) { for(size_t i = 0; i < segments; ++i, angle += delta) {
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f )); meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
} }
meshout.vertcnt.push_back(segments); meshout.vertcnt.push_back(segments);
} }
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) { else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
// construct simplified IBeam shape // construct simplified IBeam shape
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2; const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2; const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
meshout.verts.reserve(12); meshout.verts.reserve(12);
meshout.verts.push_back(IfcVector3(0,0,0)); meshout.verts.push_back(IfcVector3(0,0,0));
meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness,0)); meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness,0)); meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0)); meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0)); meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(0,ishape->OverallDepth,0)); meshout.verts.push_back(IfcVector3(0,ishape->OverallDepth,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0)); meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0)); meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0)); meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0));
meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0)); meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0)); meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0));
meshout.verts.push_back(IfcVector3(ishape->OverallWidth,0,0)); meshout.verts.push_back(IfcVector3(ishape->OverallWidth,0,0));
meshout.vertcnt.push_back(12); meshout.vertcnt.push_back(12);
} }
else { else {
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName());
return; return;
} }
IfcMatrix4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo, *def.Position); ConvertAxisPlacement(trafo, *def.Position);
meshout.Transform(trafo); meshout.Transform(trafo);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv)
{ {
if(const IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<IfcArbitraryClosedProfileDef>()) { if(const IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<IfcArbitraryClosedProfileDef>()) {
ProcessClosedProfile(*cprofile,meshout,conv); ProcessClosedProfile(*cprofile,meshout,conv);
} }
else if(const IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<IfcArbitraryOpenProfileDef>()) { else if(const IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<IfcArbitraryOpenProfileDef>()) {
ProcessOpenProfile(*copen,meshout,conv); ProcessOpenProfile(*copen,meshout,conv);
} }
else if(const IfcParameterizedProfileDef* const cparam = prof.ToPtr<IfcParameterizedProfileDef>()) { else if(const IfcParameterizedProfileDef* const cparam = prof.ToPtr<IfcParameterizedProfileDef>()) {
ProcessParametrizedProfile(*cparam,meshout,conv); ProcessParametrizedProfile(*cparam,meshout,conv);
} }
else { else {
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName()); IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName());
return false; return false;
} }
meshout.RemoveAdjacentDuplicates(); meshout.RemoveAdjacentDuplicates();
if (!meshout.vertcnt.size() || meshout.vertcnt.front() <= 1) { if (!meshout.vertcnt.size() || meshout.vertcnt.front() <= 1) {
return false; return false;
} }
return true; return true;
} }
} // ! IFC } // ! IFC
} // ! Assimp } // ! Assimp
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,429 +1,429 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IFC.cpp /** @file IFC.cpp
* @brief Implementation of the Industry Foundation Classes loader. * @brief Implementation of the Industry Foundation Classes loader.
*/ */
#ifndef INCLUDED_IFCUTIL_H #ifndef INCLUDED_IFCUTIL_H
#define INCLUDED_IFCUTIL_H #define INCLUDED_IFCUTIL_H
#include "IFCReaderGen.h" #include "IFCReaderGen.h"
#include "IFCLoader.h" #include "IFCLoader.h"
#include "STEPFile.h" #include "STEPFile.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/material.h" #include "../include/assimp/material.h"
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
typedef double IfcFloat; typedef double IfcFloat;
// IfcFloat-precision math data types // IfcFloat-precision math data types
typedef aiVector2t<IfcFloat> IfcVector2; typedef aiVector2t<IfcFloat> IfcVector2;
typedef aiVector3t<IfcFloat> IfcVector3; typedef aiVector3t<IfcFloat> IfcVector3;
typedef aiMatrix4x4t<IfcFloat> IfcMatrix4; typedef aiMatrix4x4t<IfcFloat> IfcMatrix4;
typedef aiMatrix3x3t<IfcFloat> IfcMatrix3; typedef aiMatrix3x3t<IfcFloat> IfcMatrix3;
typedef aiColor4t<IfcFloat> IfcColor4; typedef aiColor4t<IfcFloat> IfcColor4;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helper for std::for_each to delete all heap-allocated items in a container // Helper for std::for_each to delete all heap-allocated items in a container
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template<typename T> template<typename T>
struct delete_fun struct delete_fun
{ {
void operator()(T* del) { void operator()(T* del) {
delete del; delete del;
} }
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons. // Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct TempMesh struct TempMesh
{ {
std::vector<IfcVector3> verts; std::vector<IfcVector3> verts;
std::vector<unsigned int> vertcnt; std::vector<unsigned int> vertcnt;
// utilities // utilities
aiMesh* ToMesh(); aiMesh* ToMesh();
void Clear(); void Clear();
void Transform(const IfcMatrix4& mat); void Transform(const IfcMatrix4& mat);
IfcVector3 Center() const; IfcVector3 Center() const;
void Append(const TempMesh& other); void Append(const TempMesh& other);
bool IsEmpty() const { bool IsEmpty() const {
return verts.empty() && vertcnt.empty(); return verts.empty() && vertcnt.empty();
} }
void RemoveAdjacentDuplicates(); void RemoveAdjacentDuplicates();
void RemoveDegenerates(); void RemoveDegenerates();
void FixupFaceOrientation(); void FixupFaceOrientation();
static IfcVector3 ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize = true); static IfcVector3 ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize = true);
IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const; IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const;
void ComputePolygonNormals(std::vector<IfcVector3>& normals, bool normalize = true, size_t ofs = 0) const; void ComputePolygonNormals(std::vector<IfcVector3>& normals, bool normalize = true, size_t ofs = 0) const;
void Swap(TempMesh& other); void Swap(TempMesh& other);
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Temporary representation of an opening in a wall or a floor // Temporary representation of an opening in a wall or a floor
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct TempOpening struct TempOpening
{ {
const IFC::IfcSolidModel* solid; const IFC::IfcSolidModel* solid;
IfcVector3 extrusionDir; IfcVector3 extrusionDir;
boost::shared_ptr<TempMesh> profileMesh; boost::shared_ptr<TempMesh> profileMesh;
boost::shared_ptr<TempMesh> profileMesh2D; boost::shared_ptr<TempMesh> profileMesh2D;
// list of points generated for this opening. This is used to // list of points generated for this opening. This is used to
// create connections between two opposing holes created // create connections between two opposing holes created
// from a single opening instance (two because walls tend to // from a single opening instance (two because walls tend to
// have two sides). If !empty(), the other side of the wall // have two sides). If !empty(), the other side of the wall
// has already been processed. // has already been processed.
std::vector<IfcVector3> wallPoints; std::vector<IfcVector3> wallPoints;
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
TempOpening() TempOpening()
: solid() : solid()
, extrusionDir() , extrusionDir()
, profileMesh() , profileMesh()
{ {
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir, TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir,
boost::shared_ptr<TempMesh> profileMesh, boost::shared_ptr<TempMesh> profileMesh,
boost::shared_ptr<TempMesh> profileMesh2D) boost::shared_ptr<TempMesh> profileMesh2D)
: solid(solid) : solid(solid)
, extrusionDir(extrusionDir) , extrusionDir(extrusionDir)
, profileMesh(profileMesh) , profileMesh(profileMesh)
, profileMesh2D(profileMesh2D) , profileMesh2D(profileMesh2D)
{ {
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Helper to sort openings by distance from a given base point // Helper to sort openings by distance from a given base point
struct DistanceSorter { struct DistanceSorter {
DistanceSorter(const IfcVector3& base) : base(base) {} DistanceSorter(const IfcVector3& base) : base(base) {}
bool operator () (const TempOpening& a, const TempOpening& b) const { bool operator () (const TempOpening& a, const TempOpening& b) const {
return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength(); return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength();
} }
IfcVector3 base; IfcVector3 base;
}; };
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Intermediate data storage during conversion. Keeps everything and a bit more. // Intermediate data storage during conversion. Keeps everything and a bit more.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct ConversionData struct ConversionData
{ {
ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings) ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings)
: len_scale(1.0) : len_scale(1.0)
, angle_scale(-1.0) , angle_scale(-1.0)
, db(db) , db(db)
, proj(proj) , proj(proj)
, out(out) , out(out)
, settings(settings) , settings(settings)
, apply_openings() , apply_openings()
, collect_openings() , collect_openings()
{} {}
~ConversionData() { ~ConversionData() {
std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>()); std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>());
std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>()); std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
} }
IfcFloat len_scale, angle_scale; IfcFloat len_scale, angle_scale;
bool plane_angle_in_radians; bool plane_angle_in_radians;
const STEP::DB& db; const STEP::DB& db;
const IFC::IfcProject& proj; const IFC::IfcProject& proj;
aiScene* out; aiScene* out;
IfcMatrix4 wcs; IfcMatrix4 wcs;
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials; std::vector<aiMaterial*> materials;
struct MeshCacheIndex { struct MeshCacheIndex {
const IFC::IfcRepresentationItem* item; unsigned int matindex; const IFC::IfcRepresentationItem* item; unsigned int matindex;
MeshCacheIndex() : item(NULL), matindex(0) { } MeshCacheIndex() : item(NULL), matindex(0) { }
MeshCacheIndex(const IFC::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { } MeshCacheIndex(const IFC::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { }
bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; } bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); } bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }
}; };
typedef std::map<MeshCacheIndex, std::vector<unsigned int> > MeshCache; typedef std::map<MeshCacheIndex, std::vector<unsigned int> > MeshCache;
MeshCache cached_meshes; MeshCache cached_meshes;
typedef std::map<const IFC::IfcSurfaceStyle*, unsigned int> MaterialCache; typedef std::map<const IFC::IfcSurfaceStyle*, unsigned int> MaterialCache;
MaterialCache cached_materials; MaterialCache cached_materials;
const IFCImporter::Settings& settings; const IFCImporter::Settings& settings;
// Intermediate arrays used to resolve openings in walls: only one of them // Intermediate arrays used to resolve openings in walls: only one of them
// can be given at a time. apply_openings if present if the current element // can be given at a time. apply_openings if present if the current element
// is a wall and needs its openings to be poured into its geometry while // is a wall and needs its openings to be poured into its geometry while
// collect_openings is present only if the current element is an // collect_openings is present only if the current element is an
// IfcOpeningElement, for which all the geometry needs to be preserved // IfcOpeningElement, for which all the geometry needs to be preserved
// for later processing by a parent, which is a wall. // for later processing by a parent, which is a wall.
std::vector<TempOpening>* apply_openings; std::vector<TempOpening>* apply_openings;
std::vector<TempOpening>* collect_openings; std::vector<TempOpening>* collect_openings;
std::set<uint64_t> already_processed; std::set<uint64_t> already_processed;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Binary predicate to compare vectors with a given, quadratic epsilon. // Binary predicate to compare vectors with a given, quadratic epsilon.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct FuzzyVectorCompare { struct FuzzyVectorCompare {
FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {} FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
bool operator()(const IfcVector3& a, const IfcVector3& b) { bool operator()(const IfcVector3& a, const IfcVector3& b) {
return std::abs((a-b).SquareLength()) < epsilon; return std::abs((a-b).SquareLength()) < epsilon;
} }
const IfcFloat epsilon; const IfcFloat epsilon;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Ordering predicate to totally order R^2 vectors first by x and then by y // Ordering predicate to totally order R^2 vectors first by x and then by y
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct XYSorter { struct XYSorter {
// sort first by X coordinates, then by Y coordinates // sort first by X coordinates, then by Y coordinates
bool operator () (const IfcVector2&a, const IfcVector2& b) const { bool operator () (const IfcVector2&a, const IfcVector2& b) const {
if (a.x == b.x) { if (a.x == b.x) {
return a.y < b.y; return a.y < b.y;
} }
return a.x < b.x; return a.x < b.x;
} }
}; };
// conversion routines for common IFC entities, implemented in IFCUtil.cpp // conversion routines for common IFC entities, implemented in IFCUtil.cpp
void ConvertColor(aiColor4D& out, const IfcColourRgb& in); void ConvertColor(aiColor4D& out, const IfcColourRgb& in);
void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base); void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base);
void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in); void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in);
void ConvertDirection(IfcVector3& out, const IfcDirection& in); void ConvertDirection(IfcVector3& out, const IfcDirection& in);
void ConvertVector(IfcVector3& out, const IfcVector& in); void ConvertVector(IfcVector3& out, const IfcVector& in);
void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z); void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z);
void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in);
void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in);
void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in); void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in);
void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv);
void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op); void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op);
bool IsTrue(const EXPRESS::BOOLEAN& in); bool IsTrue(const EXPRESS::BOOLEAN& in);
IfcFloat ConvertSIPrefix(const std::string& prefix); IfcFloat ConvertSIPrefix(const std::string& prefix);
// IFCProfile.cpp // IFCProfile.cpp
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv); bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv); bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
// IFCMaterial.cpp // IFCMaterial.cpp
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat); unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
// IFCGeometry.cpp // IFCGeometry.cpp
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut); IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut);
bool ProcessRepresentationItem(const IfcRepresentationItem& item, unsigned int matid, std::vector<unsigned int>& mesh_indices, ConversionData& conv); bool ProcessRepresentationItem(const IfcRepresentationItem& item, unsigned int matid, std::vector<unsigned int>& mesh_indices, ConversionData& conv);
void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/); void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/);
void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
ConversionData& conv); ConversionData& conv);
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
ConversionData& conv, bool collect_openings); ConversionData& conv, bool collect_openings);
// IFCBoolean.cpp // IFCBoolean.cpp
void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv); void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv);
void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result,
const TempMesh& first_operand, const TempMesh& first_operand,
ConversionData& conv); ConversionData& conv);
void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result,
const TempMesh& first_operand, const TempMesh& first_operand,
ConversionData& conv); ConversionData& conv);
void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result,
const TempMesh& first_operand, const TempMesh& first_operand,
ConversionData& conv); ConversionData& conv);
// IFCOpenings.cpp // IFCOpenings.cpp
bool GenerateOpenings(std::vector<TempOpening>& openings, bool GenerateOpenings(std::vector<TempOpening>& openings,
const std::vector<IfcVector3>& nors, const std::vector<IfcVector3>& nors,
TempMesh& curmesh, TempMesh& curmesh,
bool check_intersection, bool check_intersection,
bool generate_connection_geometry, bool generate_connection_geometry,
const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0)); const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0));
// IFCCurve.cpp // IFCCurve.cpp
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom exception for use by members of the Curve class // Custom exception for use by members of the Curve class
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class CurveError class CurveError
{ {
public: public:
CurveError(const std::string& s) CurveError(const std::string& s)
: s(s) : s(s)
{ {
} }
std::string s; std::string s;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves // Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves
// to obtain a list of line segments. // to obtain a list of line segments.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class Curve class Curve
{ {
protected: protected:
Curve(const IfcCurve& base_entity, ConversionData& conv) Curve(const IfcCurve& base_entity, ConversionData& conv)
: base_entity(base_entity) : base_entity(base_entity)
, conv(conv) , conv(conv)
{} {}
public: public:
typedef std::pair<IfcFloat, IfcFloat> ParamRange; typedef std::pair<IfcFloat, IfcFloat> ParamRange;
public: public:
virtual ~Curve() {} virtual ~Curve() {}
// check if a curve is closed // check if a curve is closed
virtual bool IsClosed() const = 0; virtual bool IsClosed() const = 0;
// evaluate the curve at the given parametric position // evaluate the curve at the given parametric position
virtual IfcVector3 Eval(IfcFloat p) const = 0; virtual IfcVector3 Eval(IfcFloat p) const = 0;
// try to match a point on the curve to a given parameter // try to match a point on the curve to a given parameter
// for self-intersecting curves, the result is not ambiguous and // for self-intersecting curves, the result is not ambiguous and
// it is undefined which parameter is returned. // it is undefined which parameter is returned.
virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const; virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const;
// get the range of the curve (both inclusive). // get the range of the curve (both inclusive).
// +inf and -inf are valid return values, the curve is not bounded in such a case. // +inf and -inf are valid return values, the curve is not bounded in such a case.
virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0; virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0;
IfcFloat GetParametricRangeDelta() const; IfcFloat GetParametricRangeDelta() const;
// estimate the number of sample points that this curve will require // estimate the number of sample points that this curve will require
virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const; virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const;
// intelligently sample the curve based on the current settings // intelligently sample the curve based on the current settings
// and append the result to the mesh // and append the result to the mesh
virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const; virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
#ifdef ASSIMP_BUILD_DEBUG #ifdef ASSIMP_BUILD_DEBUG
// check if a particular parameter value lies within the well-defined range // check if a particular parameter value lies within the well-defined range
bool InRange(IfcFloat) const; bool InRange(IfcFloat) const;
#endif #endif
public: public:
static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv); static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv);
protected: protected:
const IfcCurve& base_entity; const IfcCurve& base_entity;
ConversionData& conv; ConversionData& conv;
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// A BoundedCurve always holds the invariant that GetParametricRange() // A BoundedCurve always holds the invariant that GetParametricRange()
// never returns infinite values. // never returns infinite values.
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
class BoundedCurve : public Curve class BoundedCurve : public Curve
{ {
public: public:
BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv) BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv)
: Curve(entity,conv) : Curve(entity,conv)
{} {}
public: public:
bool IsClosed() const; bool IsClosed() const;
public: public:
// sample the entire curve // sample the entire curve
void SampleDiscrete(TempMesh& out) const; void SampleDiscrete(TempMesh& out) const;
using Curve::SampleDiscrete; using Curve::SampleDiscrete;
}; };
// IfcProfile.cpp // IfcProfile.cpp
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv); bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
} }
} }
#endif #endif

View File

@ -1,102 +1,102 @@
// Definitions for the Interchange File Format (IFF) // Definitions for the Interchange File Format (IFF)
// Alexander Gessler, 2006 // Alexander Gessler, 2006
// Adapted to Assimp August 2008 // Adapted to Assimp August 2008
#ifndef AI_IFF_H_INCLUDED #ifndef AI_IFF_H_INCLUDED
#define AI_IFF_H_INCLUDED #define AI_IFF_H_INCLUDED
#include "ByteSwapper.h" #include "ByteSwapper.h"
namespace Assimp { namespace Assimp {
namespace IFF { namespace IFF {
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//! Describes an IFF chunk header //! Describes an IFF chunk header
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
struct ChunkHeader struct ChunkHeader
{ {
//! Type of the chunk header - FourCC //! Type of the chunk header - FourCC
uint32_t type; uint32_t type;
//! Length of the chunk data, in bytes //! Length of the chunk data, in bytes
uint32_t length; uint32_t length;
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//! Describes an IFF sub chunk header //! Describes an IFF sub chunk header
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
struct SubChunkHeader struct SubChunkHeader
{ {
//! Type of the chunk header - FourCC //! Type of the chunk header - FourCC
uint32_t type; uint32_t type;
//! Length of the chunk data, in bytes //! Length of the chunk data, in bytes
uint16_t length; uint16_t length;
}; };
#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \ #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))) ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M') #define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//! Load a chunk header //! Load a chunk header
//! @param outFile Pointer to the file data - points to the chunk data afterwards //! @param outFile Pointer to the file data - points to the chunk data afterwards
//! @return Copy of the chunk header //! @return Copy of the chunk header
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
inline ChunkHeader LoadChunk(uint8_t*& outFile) inline ChunkHeader LoadChunk(uint8_t*& outFile)
{ {
ChunkHeader head; ChunkHeader head;
::memcpy(&head.type, outFile, 4); ::memcpy(&head.type, outFile, 4);
outFile += 4; outFile += 4;
::memcpy(&head.length, outFile, 4); ::memcpy(&head.length, outFile, 4);
outFile += 4; outFile += 4;
AI_LSWAP4(head.length); AI_LSWAP4(head.length);
AI_LSWAP4(head.type); AI_LSWAP4(head.type);
return head; return head;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//! Load a sub chunk header //! Load a sub chunk header
//! @param outFile Pointer to the file data - points to the chunk data afterwards //! @param outFile Pointer to the file data - points to the chunk data afterwards
//! @return Copy of the sub chunk header //! @return Copy of the sub chunk header
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
inline SubChunkHeader LoadSubChunk(uint8_t*& outFile) inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
{ {
SubChunkHeader head; SubChunkHeader head;
::memcpy(&head.type, outFile, 4); ::memcpy(&head.type, outFile, 4);
outFile += 4; outFile += 4;
::memcpy(&head.length, outFile, 2); ::memcpy(&head.length, outFile, 2);
outFile += 2; outFile += 2;
AI_LSWAP2(head.length); AI_LSWAP2(head.length);
AI_LSWAP4(head.type); AI_LSWAP4(head.type);
return head; return head;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//! Read the file header and return the type of the file and its size //! 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 //! @param outFile Pointer to the file data. The buffer must at
//! least be 12 bytes large. //! least be 12 bytes large.
//! @param fileType Receives the type of the file //! @param fileType Receives the type of the file
//! @return 0 if everything was OK, otherwise an error message //! @return 0 if everything was OK, otherwise an error message
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType) inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
{ {
ChunkHeader head = LoadChunk(outFile); ChunkHeader head = LoadChunk(outFile);
if(AI_IFF_FOURCC_FORM != head.type) if(AI_IFF_FOURCC_FORM != head.type)
{ {
return "The file is not an IFF file: FORM chunk is missing"; return "The file is not an IFF file: FORM chunk is missing";
} }
::memcpy(&fileType, outFile, 4); ::memcpy(&fileType, outFile, 4);
AI_LSWAP4(fileType); AI_LSWAP4(fileType);
return 0; return 0;
} }
}} }}
#endif // !! AI_IFF_H_INCLUDED #endif // !! AI_IFF_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,310 +1,310 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IRRLoader.h /** @file IRRLoader.h
* @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format) * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
* importer class. * importer class.
*/ */
#ifndef AI_IRRLOADER_H_INCLUDED #ifndef AI_IRRLOADER_H_INCLUDED
#define AI_IRRLOADER_H_INCLUDED #define AI_IRRLOADER_H_INCLUDED
#include "IRRShared.h" #include "IRRShared.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "Importer.h" #include "Importer.h"
#include "../include/assimp/anim.h" #include "../include/assimp/anim.h"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Irr importer class. /** Irr importer class.
* *
* Irr is the native scene file format of the Irrlight engine and its editor * 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, * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange. * it might be a good file format for data exchange.
*/ */
class IRRImporter : public BaseImporter, public IrrlichtBase class IRRImporter : public BaseImporter, public IrrlichtBase
{ {
public: public:
IRRImporter(); IRRImporter();
~IRRImporter(); ~IRRImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** /**
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** /**
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** /**
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
private: private:
/** Data structure for a scenegraph node animator /** Data structure for a scenegraph node animator
*/ */
struct Animator struct Animator
{ {
// Type of the animator // Type of the animator
enum AT enum AT
{ {
UNKNOWN = 0x0, UNKNOWN = 0x0,
ROTATION = 0x1, ROTATION = 0x1,
FLY_CIRCLE = 0x2, FLY_CIRCLE = 0x2,
FLY_STRAIGHT = 0x3, FLY_STRAIGHT = 0x3,
FOLLOW_SPLINE = 0x4, FOLLOW_SPLINE = 0x4,
OTHER = 0x5 OTHER = 0x5
} type; } type;
Animator(AT t = UNKNOWN) Animator(AT t = UNKNOWN)
: type (t) : type (t)
, speed (0.001f) , speed (0.001f)
, direction (0.f,1.f,0.f) , direction (0.f,1.f,0.f)
, circleRadius (1.f) , circleRadius (1.f)
, tightness (0.5f) , tightness (0.5f)
, loop (true) , loop (true)
, timeForWay (100) , timeForWay (100)
{ {
} }
// common parameters // common parameters
float speed; float speed;
aiVector3D direction; aiVector3D direction;
// FLY_CIRCLE // FLY_CIRCLE
aiVector3D circleCenter; aiVector3D circleCenter;
float circleRadius; float circleRadius;
// FOLLOW_SPLINE // FOLLOW_SPLINE
float tightness; float tightness;
std::vector<aiVectorKey> splineKeys; std::vector<aiVectorKey> splineKeys;
// ROTATION (angles given in direction) // ROTATION (angles given in direction)
// FLY STRAIGHT // FLY STRAIGHT
// circleCenter = start, direction = end // circleCenter = start, direction = end
bool loop; bool loop;
int timeForWay; int timeForWay;
}; };
/** Data structure for a scenegraph node in an IRR file /** Data structure for a scenegraph node in an IRR file
*/ */
struct Node struct Node
{ {
// Type of the node // Type of the node
enum ET enum ET
{ {
LIGHT, LIGHT,
CUBE, CUBE,
MESH, MESH,
SKYBOX, SKYBOX,
DUMMY, DUMMY,
CAMERA, CAMERA,
TERRAIN, TERRAIN,
SPHERE, SPHERE,
ANIMMESH ANIMMESH
} type; } type;
Node(ET t) Node(ET t)
: type (t) : type (t)
, scaling (1.f,1.f,1.f) // assume uniform scaling by default , scaling (1.f,1.f,1.f) // assume uniform scaling by default
, framesPerSecond (0.f) , framesPerSecond (0.f)
, sphereRadius (1.f) , sphereRadius (1.f)
, spherePolyCountX (100) , spherePolyCountX (100)
, spherePolyCountY (100) , spherePolyCountY (100)
{ {
// Generate a default name for the node // Generate a default name for the node
char buffer[128]; char buffer[128];
static int cnt; static int cnt;
::sprintf(buffer,"IrrNode_%i",cnt++); ::sprintf(buffer,"IrrNode_%i",cnt++);
name = std::string(buffer); name = std::string(buffer);
// reserve space for up to 5 materials // reserve space for up to 5 materials
materials.reserve(5); materials.reserve(5);
// reserve space for up to 5 children // reserve space for up to 5 children
children.reserve(5); children.reserve(5);
} }
// Transformation of the node // Transformation of the node
aiVector3D position, rotation, scaling; aiVector3D position, rotation, scaling;
// Name of the node // Name of the node
std::string name; std::string name;
// List of all child nodes // List of all child nodes
std::vector<Node*> children; std::vector<Node*> children;
// Parent node // Parent node
Node* parent; Node* parent;
// Animated meshes: frames per second // Animated meshes: frames per second
// 0.f if not specified // 0.f if not specified
float framesPerSecond; float framesPerSecond;
// Meshes: path to the mesh to be loaded // Meshes: path to the mesh to be loaded
std::string meshPath; std::string meshPath;
unsigned int id; unsigned int id;
// Meshes: List of materials to be assigned // Meshes: List of materials to be assigned
// along with their corresponding material flags // along with their corresponding material flags
std::vector< std::pair<aiMaterial*, unsigned int> > materials; std::vector< std::pair<aiMaterial*, unsigned int> > materials;
// Spheres: radius of the sphere to be generates // Spheres: radius of the sphere to be generates
float sphereRadius; float sphereRadius;
// Spheres: Number of polygons in the x,y direction // Spheres: Number of polygons in the x,y direction
unsigned int spherePolyCountX,spherePolyCountY; unsigned int spherePolyCountX,spherePolyCountY;
// List of all animators assigned to the node // List of all animators assigned to the node
std::list<Animator> animators; std::list<Animator> animators;
}; };
/** Data structure for a vertex in an IRR skybox /** Data structure for a vertex in an IRR skybox
*/ */
struct SkyboxVertex struct SkyboxVertex
{ {
SkyboxVertex() SkyboxVertex()
{} {}
//! Construction from single vertex components //! Construction from single vertex components
SkyboxVertex(float px, float py, float pz, SkyboxVertex(float px, float py, float pz,
float nx, float ny, float nz, float nx, float ny, float nz,
float uvx, float uvy) float uvx, float uvy)
: position (px,py,pz) : position (px,py,pz)
, normal (nx,ny,nz) , normal (nx,ny,nz)
, uv (uvx,uvy,0.f) , uv (uvx,uvy,0.f)
{} {}
aiVector3D position, normal, uv; aiVector3D position, normal, uv;
}; };
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Fill the scenegraph recursively /** Fill the scenegraph recursively
*/ */
void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene, void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
BatchLoader& batch, BatchLoader& batch,
std::vector<aiMesh*>& meshes, std::vector<aiMesh*>& meshes,
std::vector<aiNodeAnim*>& anims, std::vector<aiNodeAnim*>& anims,
std::vector<AttachmentInfo>& attach, std::vector<AttachmentInfo>& attach,
std::vector<aiMaterial*>& materials, std::vector<aiMaterial*>& materials,
unsigned int& defaultMatIdx); unsigned int& defaultMatIdx);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate a mesh that consists of just a single quad /** Generate a mesh that consists of just a single quad
*/ */
aiMesh* BuildSingleQuadMesh(const SkyboxVertex& v1, aiMesh* BuildSingleQuadMesh(const SkyboxVertex& v1,
const SkyboxVertex& v2, const SkyboxVertex& v2,
const SkyboxVertex& v3, const SkyboxVertex& v3,
const SkyboxVertex& v4); const SkyboxVertex& v4);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Build a skybox /** Build a skybox
* *
* @param meshes Receives 6 output meshes * @param meshes Receives 6 output meshes
* @param materials The last 6 materials are assigned to the newly * @param materials The last 6 materials are assigned to the newly
* created meshes. The names of the materials are adjusted. * created meshes. The names of the materials are adjusted.
*/ */
void BuildSkybox(std::vector<aiMesh*>& meshes, void BuildSkybox(std::vector<aiMesh*>& meshes,
std::vector<aiMaterial*> materials); std::vector<aiMaterial*> materials);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Copy a material for a mesh to the output material list /** Copy a material for a mesh to the output material list
* *
* @param materials Receives an output material * @param materials Receives an output material
* @param inmaterials List of input materials * @param inmaterials List of input materials
* @param defMatIdx Default material index - UINT_MAX if not present * @param defMatIdx Default material index - UINT_MAX if not present
* @param mesh Mesh to work on * @param mesh Mesh to work on
*/ */
void CopyMaterial(std::vector<aiMaterial*>& materials, void CopyMaterial(std::vector<aiMaterial*>& materials,
std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials, std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
unsigned int& defMatIdx, unsigned int& defMatIdx,
aiMesh* mesh); aiMesh* mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Compute animations for a specific node /** Compute animations for a specific node
* *
* @param root Node to be processed * @param root Node to be processed
* @param anims The list of output animations * @param anims The list of output animations
*/ */
void ComputeAnimations(Node* root, aiNode* real, void ComputeAnimations(Node* root, aiNode* real,
std::vector<aiNodeAnim*>& anims); std::vector<aiNodeAnim*>& anims);
private: private:
/** Configuration option: desired output FPS */ /** Configuration option: desired output FPS */
double fps; double fps;
/** Configuration option: speed flag was set? */ /** Configuration option: speed flag was set? */
bool configSpeedFlag; bool configSpeedFlag;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_IRRIMPORTER_H_INC #endif // AI_IRRIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +1,95 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team Copyright (c) 2006-2015, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file IRRMeshLoader.h /** @file IRRMeshLoader.h
* @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format) * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
* importer class. * importer class.
*/ */
#ifndef AI_IRRMESHLOADER_H_INCLUDED #ifndef AI_IRRMESHLOADER_H_INCLUDED
#define AI_IRRMESHLOADER_H_INCLUDED #define AI_IRRMESHLOADER_H_INCLUDED
#include "BaseImporter.h" #include "BaseImporter.h"
#include "IRRShared.h" #include "IRRShared.h"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** IrrMesh importer class. /** IrrMesh importer class.
* *
* IrrMesh is the native file format of the Irrlight engine and its editor * 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, * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange. * it might be a good file format for data exchange.
*/ */
class IRRMeshImporter : public BaseImporter, public IrrlichtBase class IRRMeshImporter : public BaseImporter, public IrrlichtBase
{ {
public: public:
IRRMeshImporter(); IRRMeshImporter();
~IRRMeshImporter(); ~IRRMeshImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_IRRMESHIMPORTER_H_INC #endif // AI_IRRMESHIMPORTER_H_INC

Some files were not shown because too many files have changed in this diff Show More