Merge branch 'master' of github.com:assimp/assimp
commit
45572e8079
|
@ -0,0 +1 @@
|
||||||
|
build
|
|
@ -0,0 +1,17 @@
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get install cmake
|
||||||
|
|
||||||
|
env:
|
||||||
|
- TRAVIS_NO_EXPORT=YES
|
||||||
|
- TRAVIS_NO_EXPORT=NO
|
||||||
|
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
|
||||||
|
script: cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT && make
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@ cmake_minimum_required( VERSION 2.6 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
# Define here the needed parameters
|
# Define here the needed parameters
|
||||||
set (ASSIMP_SV_REVISION 1264)
|
|
||||||
set (ASSIMP_VERSION_MAJOR 3)
|
set (ASSIMP_VERSION_MAJOR 3)
|
||||||
set (ASSIMP_VERSION_MINOR 0)
|
set (ASSIMP_VERSION_MINOR 0)
|
||||||
set (ASSIMP_VERSION_PATCH ${ASSIMP_SV_REVISION}) # subversion revision?
|
set (ASSIMP_VERSION_PATCH 1) # subversion revision?
|
||||||
set (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
set (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
||||||
set (ASSIMP_SOVERSION 3)
|
set (ASSIMP_SOVERSION 3)
|
||||||
SET ( PROJECT_VERSION "${ASSIMP_VERSION}" )
|
SET ( PROJECT_VERSION "${ASSIMP_VERSION}" )
|
||||||
|
@ -14,19 +13,25 @@ set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used f
|
||||||
|
|
||||||
option(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
option(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
|
||||||
set(LIBASSIMP_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}-r${ASSIMP_SV_REVISION})
|
set(LIBASSIMP_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
||||||
set(LIBASSIMP-DEV_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}-r${ASSIMP_SV_REVISION}-dev)
|
set(LIBASSIMP-DEV_COMPONENT libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev)
|
||||||
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
||||||
|
set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
|
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
|
||||||
## hide all not-exported symbols
|
## hide all not-exported symbols
|
||||||
add_definitions( -fvisibility=hidden -Wall )
|
add_definitions( -fvisibility=hidden -Wall )
|
||||||
|
elseif(MSVC)
|
||||||
|
# enable multi-core compilation with MSVC
|
||||||
|
add_definitions(/MP)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
INCLUDE (FindPkgConfig)
|
INCLUDE (FindPkgConfig)
|
||||||
INCLUDE_DIRECTORIES( include )
|
INCLUDE_DIRECTORIES( include )
|
||||||
|
|
||||||
|
INCLUDE (PrecompiledHeader)
|
||||||
|
|
||||||
# If this is an in-source build (CMAKE_SOURCE_DIR == CMAKE_BINARY_DIR),
|
# If this is an in-source build (CMAKE_SOURCE_DIR == CMAKE_BINARY_DIR),
|
||||||
# write the library/executable files to the respective directories in the
|
# write the library/executable files to the respective directories in the
|
||||||
# source tree. During an out-of-source build, however, do not litter this
|
# source tree. During an out-of-source build, however, do not litter this
|
||||||
|
@ -76,7 +81,7 @@ IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
MESSAGE( STATUS "Building a non-boost version of Assimp." )
|
MESSAGE( STATUS "Building a non-boost version of Assimp." )
|
||||||
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
SET( Boost_DETAILED_FAILURE_MSG ON )
|
SET( Boost_DETAILED_FAILURE_MSG ON )
|
||||||
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0")
|
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0")
|
||||||
FIND_PACKAGE( Boost )
|
FIND_PACKAGE( Boost )
|
||||||
IF ( NOT Boost_FOUND )
|
IF ( NOT Boost_FOUND )
|
||||||
MESSAGE( FATAL_ERROR
|
MESSAGE( FATAL_ERROR
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
===============================================
|
||||||
|
The Asset-Importer-Library Coding conventions
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
If you want to participate to the Asset-Importer_Library please have a look
|
||||||
|
onto these coding conventions and try to follow them. They are more or less
|
||||||
|
some kind of guide line to help others coming into the code and help all
|
||||||
|
the Asset-Importer-Library users.
|
||||||
|
|
||||||
|
Tab width
|
||||||
|
===========
|
||||||
|
The tab width shall be 4 spaces.
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[InternetShortcut]
|
|
||||||
URL=http://sourceforge.net/projects/assimp/
|
|
29
Readme.md
29
Readme.md
|
@ -1,28 +1,11 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
========
|
========
|
||||||
|
|
||||||
|
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a single, in-memory format__. It supports more than 30 file formats. It also supports exporting files to a few selected file formats.
|
||||||
|
|
||||||
Table of contents
|
Its abbreviated name under which it is commonly known is __assimp__.
|
||||||
|
|
||||||
1. Overview
|
|
||||||
1.1 Supported file formats
|
|
||||||
1.2 File structure
|
|
||||||
2. Build the library
|
|
||||||
3. Where to get help
|
|
||||||
4. License
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1. Overview ###
|
|
||||||
|
|
||||||
|
|
||||||
Open Asset Import Library is a Open Source library designed to load various 3d file formats and convert them into a shared, in-memory format. It supports more than 30 file formats. It also supports exporting files to a few selected file formats.
|
|
||||||
|
|
||||||
Its short name is _assimp_, which is an unintended joke (the abbreviation is derived from _Asset Importer_).
|
|
||||||
|
|
||||||
__Note__: this `README` refers to the file structure used by release packages, which differs in some points from the development trunk.
|
|
||||||
|
|
||||||
|
This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
||||||
|
|
||||||
#### 1.1 Supported file formats ####
|
#### 1.1 Supported file formats ####
|
||||||
|
|
||||||
|
@ -62,6 +45,10 @@ The library provides importers for a lot of file formats, including:
|
||||||
- NDO
|
- NDO
|
||||||
- Ogre XML
|
- Ogre XML
|
||||||
- Q3D
|
- Q3D
|
||||||
|
|
||||||
|
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries.
|
||||||
|
|
||||||
|
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
||||||
|
|
||||||
Exporters include:
|
Exporters include:
|
||||||
|
|
||||||
|
@ -129,5 +116,3 @@ The license of the Asset Import Library is based on the modified, __3-clause BSD
|
||||||
Note that, unlike LGPLed code, you may link statically to Assimp.
|
Note that, unlike LGPLed code, you may link statically to Assimp.
|
||||||
For the formal details, see the `LICENSE` file.
|
For the formal details, see the `LICENSE` file.
|
||||||
|
|
||||||
|
|
||||||
------------------------------
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[InternetShortcut]
|
|
||||||
URL=http://assimp.sourceforge.net
|
|
|
@ -1,13 +1,13 @@
|
||||||
set( ASSIMP_PACKAGE_VERSION "@ASSIMP_VERSION@" )
|
set( PACKAGE_VERSION "@ASSIMP_VERSION@" )
|
||||||
if( "${ASSIMP_PACKAGE_FIND_VERSION}" VERSION_EQUAL "@ASSIMP_VERSION@")
|
if( "${PACKAGE_FIND_VERSION}" VERSION_EQUAL "@ASSIMP_VERSION@")
|
||||||
set(ASSIMP_PACKAGE_VERSION_EXACT 1)
|
set(PACKAGE_VERSION_EXACT 1)
|
||||||
endif()
|
endif()
|
||||||
if( "${ASSIMP_PACKAGE_FIND_VERSION_MAJOR}.${ASSIMP_PACKAGE_FIND_VERSION_MINOR}" EQUAL "@ASSIMP_SOVERSION@" )
|
if( "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}" EQUAL "@ASSIMP_SOVERSION@" )
|
||||||
set(ASSIMP_PACKAGE_VERSION_COMPATIBLE 1)
|
set(PACKAGE_VERSION_COMPATIBLE 1)
|
||||||
elseif( "${ASSIMP_PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@ASSIMP_VERSION_MAJOR@" )
|
elseif( "${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@ASSIMP_VERSION_MAJOR@" )
|
||||||
# for now backward compatible if minor version is less
|
# for now backward compatible if minor version is less
|
||||||
if( ${ASSIMP_PACKAGE_FIND_VERSION_MINOR} LESS @ASSIMP_VERSION_MINOR@ )
|
if( ${PACKAGE_FIND_VERSION_MINOR} LESS @ASSIMP_VERSION_MINOR@ )
|
||||||
set(ASSIMP_PACKAGE_VERSION_COMPATIBLE 1)
|
set(PACKAGE_VERSION_COMPATIBLE 1)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
set( ASSIMP_STATIC_LIB "@ASSIMP_BUILD_STATIC_LIB@")
|
set( ASSIMP_STATIC_LIB "@ASSIMP_BUILD_STATIC_LIB@")
|
||||||
|
|
|
@ -37,8 +37,8 @@ if( WIN32 )
|
||||||
set( ASSIMP_CXX_FLAGS " -DBOOST_ALL_DYN_LINK -DBOOST_ALL_NO_LIB")
|
set( ASSIMP_CXX_FLAGS " -DBOOST_ALL_DYN_LINK -DBOOST_ALL_NO_LIB")
|
||||||
endif()
|
endif()
|
||||||
set( ASSIMP_LINK_FLAGS "" )
|
set( ASSIMP_LINK_FLAGS "" )
|
||||||
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@LIB_INSTALL_DIR@")
|
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
|
||||||
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@INCLUDE_INSTALL_DIR@")
|
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
|
||||||
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
|
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
|
||||||
|
|
||||||
# the boost version assimp was compiled with
|
# the boost version assimp was compiled with
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
|
||||||
|
IF(MSVC)
|
||||||
|
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
|
||||||
|
SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
|
||||||
|
SET(Sources ${${SourcesVar}})
|
||||||
|
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
|
||||||
|
OBJECT_OUTPUTS "${PrecompiledBinary}")
|
||||||
|
|
||||||
|
# Do not consider .c files
|
||||||
|
foreach(fname ${Sources})
|
||||||
|
GET_FILENAME_COMPONENT(fext ${fname} EXT)
|
||||||
|
if(fext STREQUAL ".cpp")
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${fname}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
|
||||||
|
OBJECT_DEPENDS "${PrecompiledBinary}")
|
||||||
|
endif(fext STREQUAL ".cpp")
|
||||||
|
endforeach(fname)
|
||||||
|
|
||||||
|
ENDIF(MSVC)
|
||||||
|
# Add precompiled header to SourcesVar
|
||||||
|
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
|
||||||
|
|
||||||
|
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
|
|
@ -707,7 +707,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
if (0 == mRootNode->mChildren.size())
|
if (0 == mRootNode->mChildren.size())
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// It seems the file is so fucked up that it has not even a hierarchy.
|
// It seems the file is so messed up that it has not even a hierarchy.
|
||||||
// generate a flat hiearachy which looks like this:
|
// generate a flat hiearachy which looks like this:
|
||||||
//
|
//
|
||||||
// ROOT_NODE
|
// ROOT_NODE
|
||||||
|
|
|
@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/assimp/types.h"
|
#include "../include/assimp/types.h"
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
#include "3DSHelper.h"
|
#include "3DSHelper.h"
|
||||||
|
|
||||||
|
@ -271,6 +273,8 @@ protected:
|
||||||
bool bIsPrj;
|
bool bIsPrj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // AI_3DSIMPORTER_H_INC
|
#endif // AI_3DSIMPORTER_H_INC
|
||||||
|
|
|
@ -1567,8 +1567,8 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
|
||||||
unsigned int iIndex = strtoul10(filePtr,&filePtr);
|
unsigned int iIndex = strtoul10(filePtr,&filePtr);
|
||||||
if (iIndex >= iNumBones)
|
if (iIndex >= iNumBones)
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
LogWarning("Bone index is out of bounds");
|
LogWarning("Bone index is out of bounds");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
|
if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
|
||||||
SkipToNextToken();
|
SkipToNextToken();
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
@ -624,7 +625,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef std::pair<const int,size_t> MyPair;
|
typedef std::pair<const int,size_t> MyPair;
|
||||||
if (!mesh->totface || !mesh->totvert) {
|
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,12 +638,24 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
ThrowException("Number of vertices is larger than the corresponding array");
|
ThrowException("Number of vertices is larger than the corresponding array");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (static_cast<size_t> ( mesh->totloop ) > mesh->mloop.size()) {
|
||||||
|
ThrowException("Number of vertices is larger than the corresponding array");
|
||||||
|
}
|
||||||
|
|
||||||
// collect per-submesh numbers
|
// collect per-submesh numbers
|
||||||
std::map<int,size_t> per_mat;
|
std::map<int,size_t> per_mat;
|
||||||
|
std::map<int,size_t> per_mat_verts;
|
||||||
for (int i = 0; i < mesh->totface; ++i) {
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
|
|
||||||
const MFace& mf = mesh->mface[i];
|
const MFace& mf = mesh->mface[i];
|
||||||
per_mat[ mf.mat_nr ]++;
|
per_mat[ mf.mat_nr ]++;
|
||||||
|
per_mat_verts[ mf.mat_nr ] += mf.v4?4:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totpoly; ++i) {
|
||||||
|
const MPoly& mp = mesh->mpoly[i];
|
||||||
|
per_mat[ mp.mat_nr ]++;
|
||||||
|
per_mat_verts[ mp.mat_nr ] += mp.totloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and allocate the corresponding meshes
|
// ... and allocate the corresponding meshes
|
||||||
|
@ -656,8 +669,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
temp->push_back(new aiMesh());
|
temp->push_back(new aiMesh());
|
||||||
|
|
||||||
aiMesh* out = temp->back();
|
aiMesh* out = temp->back();
|
||||||
out->mVertices = new aiVector3D[it.second*4];
|
out->mVertices = new aiVector3D[per_mat_verts[it.first]];
|
||||||
out->mNormals = new aiVector3D[it.second*4];
|
out->mNormals = new aiVector3D[per_mat_verts[it.first]];
|
||||||
|
|
||||||
//out->mNumFaces = 0
|
//out->mNumFaces = 0
|
||||||
//out->mNumVertices = 0
|
//out->mNumVertices = 0
|
||||||
|
@ -780,8 +793,56 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totpoly; ++i) {
|
||||||
|
|
||||||
|
const MPoly& mf = mesh->mpoly[i];
|
||||||
|
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
|
||||||
|
aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
f.mIndices = new unsigned int[ f.mNumIndices = mf.totloop ];
|
||||||
|
aiVector3D* vo = out->mVertices + out->mNumVertices;
|
||||||
|
aiVector3D* vn = out->mNormals + out->mNumVertices;
|
||||||
|
|
||||||
|
// XXX we can't fold this easily, because we are restricted
|
||||||
|
// to the member names from the BLEND file (v1,v2,v3,v4)
|
||||||
|
// which are assigned by the genblenddna.py script and
|
||||||
|
// cannot be changed without breaking the entire
|
||||||
|
// import process.
|
||||||
|
for (int j = 0;j < mf.totloop; ++j)
|
||||||
|
{
|
||||||
|
const MLoop& loop = mesh->mloop[mf.loopstart + j];
|
||||||
|
|
||||||
|
if (loop.v >= mesh->totvert) {
|
||||||
|
ThrowException("Vertex index out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
const MVert& v = mesh->mvert[loop.v];
|
||||||
|
|
||||||
|
vo->x = v.co[0];
|
||||||
|
vo->y = v.co[1];
|
||||||
|
vo->z = v.co[2];
|
||||||
|
vn->x = v.no[0];
|
||||||
|
vn->y = v.no[1];
|
||||||
|
vn->z = v.no[2];
|
||||||
|
f.mIndices[j] = out->mNumVertices++;
|
||||||
|
|
||||||
|
++vo;
|
||||||
|
++vn;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (mf.totloop == 3)
|
||||||
|
{
|
||||||
|
out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// collect texture coordinates, they're stored in a separate per-face buffer
|
// collect texture coordinates, they're stored in a separate per-face buffer
|
||||||
if (mesh->mtface) {
|
if (mesh->mtface || mesh->mloopuv) {
|
||||||
if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
|
if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
|
||||||
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
|
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
|
||||||
}
|
}
|
||||||
|
@ -804,6 +865,20 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
vo->y = v->uv[i][1];
|
vo->y = v->uv[i][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totpoly; ++i) {
|
||||||
|
const MPoly& v = mesh->mpoly[i];
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
|
||||||
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
||||||
|
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
||||||
|
const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
|
||||||
|
vo->x = uv.uv[0];
|
||||||
|
vo->y = uv.uv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect texture coordinates, old-style (marked as deprecated in current blender sources)
|
// collect texture coordinates, old-style (marked as deprecated in current blender sources)
|
||||||
|
@ -833,7 +908,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect vertex colors, stored separately as well
|
// collect vertex colors, stored separately as well
|
||||||
if (mesh->mcol) {
|
if (mesh->mcol || mesh->mloopcol) {
|
||||||
if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
|
if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
|
||||||
ThrowException("Number of faces is larger than the corresponding color face array");
|
ThrowException("Number of faces is larger than the corresponding color face array");
|
||||||
}
|
}
|
||||||
|
@ -860,6 +935,23 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
for (unsigned int n = f.mNumIndices; n < 4; ++n);
|
for (unsigned int n = f.mNumIndices; n < 4; ++n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totpoly; ++i) {
|
||||||
|
const MPoly& v = mesh->mpoly[i];
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
|
||||||
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
aiColor4D* vo = &out->mColors[0][out->mNumVertices];
|
||||||
|
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
||||||
|
const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
|
||||||
|
vo->r = col.r;
|
||||||
|
vo->g = col.g;
|
||||||
|
vo->b = col.b;
|
||||||
|
vo->a = col.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -94,6 +94,7 @@ namespace Assimp {
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
struct MTex;
|
struct MTex;
|
||||||
|
struct Image;
|
||||||
|
|
||||||
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
|
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
|
||||||
|
|
||||||
|
@ -156,6 +157,38 @@ struct MEdge : ElemBase {
|
||||||
short flag;
|
short flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
struct MLoop : ElemBase {
|
||||||
|
int v, e;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
struct MLoopUV : ElemBase {
|
||||||
|
float uv[2];
|
||||||
|
int flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
// Note that red and blue are not swapped, as with MCol
|
||||||
|
struct MLoopCol : ElemBase {
|
||||||
|
char r, g, b, a;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
struct MPoly : ElemBase {
|
||||||
|
int loopstart;
|
||||||
|
int totloop;
|
||||||
|
short mat_nr;
|
||||||
|
char flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
struct MTexPoly : ElemBase {
|
||||||
|
Image* tpage;
|
||||||
|
char flag, transp;
|
||||||
|
short mode, tile, pad;
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MCol : ElemBase {
|
struct MCol : ElemBase {
|
||||||
char r,g,b,a FAIL;
|
char r,g,b,a FAIL;
|
||||||
|
@ -235,6 +268,8 @@ struct Mesh : ElemBase {
|
||||||
int totface FAIL;
|
int totface FAIL;
|
||||||
int totedge FAIL;
|
int totedge FAIL;
|
||||||
int totvert FAIL;
|
int totvert FAIL;
|
||||||
|
int totloop;
|
||||||
|
int totpoly;
|
||||||
|
|
||||||
short subdiv;
|
short subdiv;
|
||||||
short subdivr;
|
short subdivr;
|
||||||
|
@ -246,6 +281,11 @@ struct Mesh : ElemBase {
|
||||||
vector<TFace> tface;
|
vector<TFace> tface;
|
||||||
vector<MVert> mvert FAIL;
|
vector<MVert> mvert FAIL;
|
||||||
vector<MEdge> medge WARN;
|
vector<MEdge> medge WARN;
|
||||||
|
vector<MLoop> mloop;
|
||||||
|
vector<MLoopUV> mloopuv;
|
||||||
|
vector<MLoopCol> mloopcol;
|
||||||
|
vector<MPoly> mpoly;
|
||||||
|
vector<MTexPoly> mtpoly;
|
||||||
vector<MDeformVert> dvert;
|
vector<MDeformVert> dvert;
|
||||||
vector<MCol> mcol;
|
vector<MCol> mcol;
|
||||||
|
|
||||||
|
|
|
@ -47,174 +47,204 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
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<Mesh> (
|
template <> void Structure :: Convert<MTexPoly> (
|
||||||
Mesh& dest,
|
MTexPoly& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MDeformVert> (
|
template <> void Structure :: Convert<Mesh> (
|
||||||
MDeformVert& dest,
|
Mesh& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<World> (
|
template <> void Structure :: Convert<MDeformVert> (
|
||||||
World& dest,
|
MDeformVert& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MVert> (
|
template <> void Structure :: Convert<World> (
|
||||||
MVert& dest,
|
World& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MEdge> (
|
template <> void Structure :: Convert<MLoopCol> (
|
||||||
MEdge& dest,
|
MLoopCol& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<GroupObject> (
|
template <> void Structure :: Convert<MVert> (
|
||||||
GroupObject& dest,
|
MVert& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ListBase> (
|
template <> void Structure :: Convert<MEdge> (
|
||||||
ListBase& dest,
|
MEdge& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ModifierData> (
|
template <> void Structure :: Convert<MLoopUV> (
|
||||||
ModifierData& dest,
|
MLoopUV& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<ID> (
|
template <> void Structure :: Convert<GroupObject> (
|
||||||
ID& dest,
|
GroupObject& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MCol> (
|
template <> void Structure :: Convert<ListBase> (
|
||||||
MCol& dest,
|
ListBase& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Image> (
|
template <> void Structure :: Convert<MLoop> (
|
||||||
Image& dest,
|
MLoop& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Scene> (
|
template <> void Structure :: Convert<ModifierData> (
|
||||||
Scene& dest,
|
ModifierData& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Library> (
|
template <> void Structure :: Convert<ID> (
|
||||||
Library& dest,
|
ID& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Tex> (
|
template <> void Structure :: Convert<MCol> (
|
||||||
Tex& dest,
|
MCol& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<Camera> (
|
template <> void Structure :: Convert<MPoly> (
|
||||||
Camera& dest,
|
MPoly& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
template <> void Structure :: Convert<MirrorModifierData> (
|
template <> void Structure :: Convert<Scene> (
|
||||||
MirrorModifierData& dest,
|
Scene& dest,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
;
|
;
|
||||||
|
|
||||||
|
template <> void Structure :: Convert<Library> (
|
||||||
|
Library& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
template <> void Structure :: Convert<Tex> (
|
||||||
|
Tex& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
template <> void Structure :: Convert<Camera> (
|
||||||
|
Camera& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
template <> void Structure :: Convert<MirrorModifierData> (
|
||||||
|
MirrorModifierData& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
template <> void Structure :: Convert<Image> (
|
||||||
|
Image& dest,
|
||||||
|
const FileDatabase& db
|
||||||
|
) const
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,9 +88,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Read(void* pvBuffer,
|
virtual size_t Read( void *,
|
||||||
size_t pSize,
|
size_t,
|
||||||
size_t pCount)
|
size_t )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
||||||
#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -175,13 +175,13 @@ namespace boost {
|
||||||
// Get a specific tuple element
|
// Get a specific tuple element
|
||||||
template <unsigned N>
|
template <unsigned N>
|
||||||
typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () {
|
typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () {
|
||||||
return m.get<N>();
|
return m.template get<N>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and the const version
|
// ... and the const version
|
||||||
template <unsigned N>
|
template <unsigned N>
|
||||||
const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const {
|
const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const {
|
||||||
return m.get<N>();
|
return m.template get<N>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,14 +208,14 @@ namespace boost {
|
||||||
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
||||||
inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
||||||
tuple<T0,T1,T2,T3,T4>& m) {
|
tuple<T0,T1,T2,T3,T4>& m) {
|
||||||
return m.get<N>();
|
return m.template get<N>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and the const version
|
// ... and the const version
|
||||||
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
||||||
inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
||||||
const tuple<T0,T1,T2,T3,T4>& m) {
|
const tuple<T0,T1,T2,T3,T4>& m) {
|
||||||
return m.get<N>();
|
return m.template get<N>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a tuple with 5 elements
|
// Constructs a tuple with 5 elements
|
||||||
|
@ -224,11 +224,11 @@ namespace boost {
|
||||||
const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
|
const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
|
||||||
|
|
||||||
tuple <T0,T1,T2,T3,T4> t;
|
tuple <T0,T1,T2,T3,T4> t;
|
||||||
t.get<0>() = t0;
|
t.template get<0>() = t0;
|
||||||
t.get<1>() = t1;
|
t.template get<1>() = t1;
|
||||||
t.get<2>() = t2;
|
t.template get<2>() = t2;
|
||||||
t.get<3>() = t3;
|
t.template get<3>() = t3;
|
||||||
t.get<4>() = t4;
|
t.template get<4>() = t4;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,10 +237,10 @@ namespace boost {
|
||||||
inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
|
inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
|
||||||
const T1& t1,const T2& t2,const T3& t3) {
|
const T1& t1,const T2& t2,const T3& t3) {
|
||||||
tuple <T0,T1,T2,T3> t;
|
tuple <T0,T1,T2,T3> t;
|
||||||
t.get<0>() = t0;
|
t.template get<0>() = t0;
|
||||||
t.get<1>() = t1;
|
t.template get<1>() = t1;
|
||||||
t.get<2>() = t2;
|
t.template get<2>() = t2;
|
||||||
t.get<3>() = t3;
|
t.template get<3>() = t3;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,31 +249,31 @@ namespace boost {
|
||||||
inline tuple <T0,T1,T2> make_tuple (const T0& t0,
|
inline tuple <T0,T1,T2> make_tuple (const T0& t0,
|
||||||
const T1& t1,const T2& t2) {
|
const T1& t1,const T2& t2) {
|
||||||
tuple <T0,T1,T2> t;
|
tuple <T0,T1,T2> t;
|
||||||
t.get<0>() = t0;
|
t.template get<0>() = t0;
|
||||||
t.get<1>() = t1;
|
t.template get<1>() = t1;
|
||||||
t.get<2>() = t2;
|
t.template get<2>() = t2;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a tuple with 2 elements (fucking idiot, use std::pair instead!)
|
// Constructs a tuple with 2 elements
|
||||||
template <typename T0,typename T1>
|
template <typename T0,typename T1>
|
||||||
inline tuple <T0,T1> make_tuple (const T0& t0,
|
inline tuple <T0,T1> make_tuple (const T0& t0,
|
||||||
const T1& t1) {
|
const T1& t1) {
|
||||||
tuple <T0,T1> t;
|
tuple <T0,T1> t;
|
||||||
t.get<0>() = t0;
|
t.template get<0>() = t0;
|
||||||
t.get<1>() = t1;
|
t.template get<1>() = t1;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a tuple with 1 elements (no comment ...)
|
// Constructs a tuple with 1 elements (well ...)
|
||||||
template <typename T0>
|
template <typename T0>
|
||||||
inline tuple <T0> make_tuple (const T0& t0) {
|
inline tuple <T0> make_tuple (const T0& t0) {
|
||||||
tuple <T0> t;
|
tuple <T0> t;
|
||||||
t.get<0>() = t0;
|
t.template get<0>() = t0;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a tuple with 0 elements (ehm? Try http://www.promillerechner.net)
|
// Constructs a tuple with 0 elements (well ...)
|
||||||
inline tuple <> make_tuple () {
|
inline tuple <> make_tuple () {
|
||||||
tuple <> t;
|
tuple <> t;
|
||||||
return t;
|
return t;
|
||||||
|
|
|
@ -34,6 +34,7 @@ SET( PUBLIC_HEADERS
|
||||||
${HEADER_PATH}/quaternion.h
|
${HEADER_PATH}/quaternion.h
|
||||||
${HEADER_PATH}/quaternion.inl
|
${HEADER_PATH}/quaternion.inl
|
||||||
${HEADER_PATH}/scene.h
|
${HEADER_PATH}/scene.h
|
||||||
|
${HEADER_PATH}/metadata.h
|
||||||
${HEADER_PATH}/texture.h
|
${HEADER_PATH}/texture.h
|
||||||
${HEADER_PATH}/types.h
|
${HEADER_PATH}/types.h
|
||||||
${HEADER_PATH}/vector2.h
|
${HEADER_PATH}/vector2.h
|
||||||
|
@ -57,8 +58,6 @@ SET( PUBLIC_HEADERS
|
||||||
|
|
||||||
SET( Core_SRCS
|
SET( Core_SRCS
|
||||||
Assimp.cpp
|
Assimp.cpp
|
||||||
AssimpPCH.cpp
|
|
||||||
AssimpPCH.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( Boost_SRCS
|
SET( Boost_SRCS
|
||||||
|
@ -237,11 +236,7 @@ SET( LWS_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
||||||
|
|
||||||
SET ( M3_SRCS
|
|
||||||
M3Importer.cpp
|
|
||||||
M3Importer.h
|
|
||||||
)
|
|
||||||
SOURCE_GROUP( M3 FILES ${M3_SRCS} )
|
|
||||||
|
|
||||||
SET( MD2_SRCS
|
SET( MD2_SRCS
|
||||||
MD2FileData.h
|
MD2FileData.h
|
||||||
|
@ -619,7 +614,7 @@ else (UNZIP_FOUND)
|
||||||
SET (unzip_compile_SRCS ${unzip_SRCS})
|
SET (unzip_compile_SRCS ${unzip_SRCS})
|
||||||
endif (UNZIP_FOUND)
|
endif (UNZIP_FOUND)
|
||||||
|
|
||||||
SET( assim_src
|
SET( assimp_src
|
||||||
# Assimp Files
|
# Assimp Files
|
||||||
${Core_SRCS}
|
${Core_SRCS}
|
||||||
${Common_SRCS}
|
${Common_SRCS}
|
||||||
|
@ -640,7 +635,6 @@ SET( assim_src
|
||||||
${Irr_SRCS}
|
${Irr_SRCS}
|
||||||
${LWO_SRCS}
|
${LWO_SRCS}
|
||||||
${LWS_SRCS}
|
${LWS_SRCS}
|
||||||
${M3_SRCS}
|
|
||||||
${MD2_SRCS}
|
${MD2_SRCS}
|
||||||
${MD3_SRCS}
|
${MD3_SRCS}
|
||||||
${MD5_SRCS}
|
${MD5_SRCS}
|
||||||
|
@ -680,13 +674,16 @@ SET( assim_src
|
||||||
${PUBLIC_HEADERS}
|
${PUBLIC_HEADERS}
|
||||||
${COMPILER_HEADERS}
|
${COMPILER_HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ADD_MSVC_PRECOMPILED_HEADER("AssimpPCH.h" "AssimpPCH.cpp" assimp_src)
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_STATIC_LIB )
|
IF ( ASSIMP_BUILD_STATIC_LIB )
|
||||||
ADD_LIBRARY( assimp STATIC
|
ADD_LIBRARY( assimp STATIC
|
||||||
${assim_src}
|
${assimp_src}
|
||||||
)
|
)
|
||||||
ELSE ( ASSIMP_BUILD_STATIC_LIB )
|
ELSE ( ASSIMP_BUILD_STATIC_LIB )
|
||||||
ADD_LIBRARY( assimp SHARED
|
ADD_LIBRARY( assimp SHARED
|
||||||
${assim_src}
|
${assimp_src}
|
||||||
)
|
)
|
||||||
ENDIF ( ASSIMP_BUILD_STATIC_LIB )
|
ENDIF ( ASSIMP_BUILD_STATIC_LIB )
|
||||||
|
|
||||||
|
@ -696,6 +693,7 @@ TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
|
||||||
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
||||||
VERSION ${ASSIMP_VERSION}
|
VERSION ${ASSIMP_VERSION}
|
||||||
SOVERSION ${ASSIMP_SOVERSION} # use full version
|
SOVERSION ${ASSIMP_SOVERSION} # use full version
|
||||||
|
OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX}
|
||||||
)
|
)
|
||||||
# Build against external unzip, or add ../contrib/unzip so
|
# Build against external unzip, or add ../contrib/unzip so
|
||||||
# assimp can #include "unzip.h"
|
# assimp can #include "unzip.h"
|
||||||
|
|
|
@ -1045,9 +1045,9 @@ void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const
|
||||||
v.y = reader.GetF4();
|
v.y = reader.GetF4();
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t numfuck = reader.GetI4();
|
const size_t numf = reader.GetI4();
|
||||||
msh.faces.reserve(numfuck);
|
msh.faces.reserve(numf);
|
||||||
for(size_t i = 0; i < numfuck; ++i) {
|
for(size_t i = 0; i < numf; ++i) {
|
||||||
// XXX backface culling flag is 0x10 in flags
|
// XXX backface culling flag is 0x10 in flags
|
||||||
|
|
||||||
// hole?
|
// hole?
|
||||||
|
|
|
@ -58,6 +58,9 @@ void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pS
|
||||||
|
|
||||||
// we're still here - export successfully completed. Write result to the given IOSYstem
|
// we're still here - export successfully completed. Write result to the given IOSYstem
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .dae file: " + std::string(pFile));
|
||||||
|
}
|
||||||
|
|
||||||
// XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
|
// XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
|
||||||
outfile->Write( iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()),1);
|
outfile->Write( iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()),1);
|
||||||
|
@ -99,7 +102,7 @@ void ColladaExporter::WriteFile()
|
||||||
|
|
||||||
WriteSceneLibrary();
|
WriteSceneLibrary();
|
||||||
|
|
||||||
// useless Collada bullshit at the end, just in case we haven't had enough indirections, yet.
|
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||||
mOutput << startstr << "<scene>" << endstr;
|
mOutput << startstr << "<scene>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_visual_scene url=\"#myScene\" />" << endstr;
|
mOutput << startstr << "<instance_visual_scene url=\"#myScene\" />" << endstr;
|
||||||
|
@ -495,7 +498,7 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
mOutput << "</float_array>" << endstr;
|
mOutput << "</float_array>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
|
||||||
// the usual Collada bullshit. Let's bloat it even more!
|
// the usual Collada fun. Let's bloat it even more!
|
||||||
mOutput << startstr << "<technique_common>" << endstr;
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<accessor count=\"" << pElementCount << "\" offset=\"0\" source=\"#" << arrayId << "\" stride=\"" << floatsPerElement << "\">" << endstr;
|
mOutput << startstr << "<accessor count=\"" << pElementCount << "\" offset=\"0\" source=\"#" << arrayId << "\" stride=\"" << floatsPerElement << "\">" << endstr;
|
||||||
|
|
|
@ -119,6 +119,7 @@ struct Camera
|
||||||
};
|
};
|
||||||
|
|
||||||
#define aiLightSource_AMBIENT 0xdeaddead
|
#define aiLightSource_AMBIENT 0xdeaddead
|
||||||
|
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
|
||||||
|
|
||||||
/** A collada light source. */
|
/** A collada light source. */
|
||||||
struct Light
|
struct Light
|
||||||
|
@ -129,8 +130,8 @@ struct Light
|
||||||
, mAttQuadratic (0.f)
|
, mAttQuadratic (0.f)
|
||||||
, mFalloffAngle (180.f)
|
, mFalloffAngle (180.f)
|
||||||
, mFalloffExponent (0.f)
|
, mFalloffExponent (0.f)
|
||||||
, mPenumbraAngle (10e10f)
|
, mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||||
, mOuterAngle (10e10f)
|
, mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||||
, mIntensity (1.f)
|
, mIntensity (1.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -320,6 +321,8 @@ struct Mesh
|
||||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
||||||
mNumUVComponents[i] = 2;
|
mNumUVComponents[i] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
// just to check if there's some sophisticated addressing involved...
|
// just to check if there's some sophisticated addressing involved...
|
||||||
// which we don't support, and therefore should warn about.
|
// which we don't support, and therefore should warn about.
|
||||||
|
|
|
@ -73,7 +73,7 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ColladaLoader::ColladaLoader()
|
ColladaLoader::ColladaLoader()
|
||||||
: noSkeletonMesh()
|
: noSkeletonMesh(), ignoreUpDirection(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -108,6 +108,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
||||||
void ColladaLoader::SetupProperties(const Importer* pImp)
|
void ColladaLoader::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||||
|
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,20 +156,26 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
// ... then fill the materials with the now adjusted settings
|
// ... then fill the materials with the now adjusted settings
|
||||||
FillMaterials(parser, pScene);
|
FillMaterials(parser, pScene);
|
||||||
|
|
||||||
// Convert to Y_UP, if different orientation
|
// Apply unitsize scale calculation
|
||||||
if( parser.mUpDirection == ColladaParser::UP_X)
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
0, parser.mUnitSize, 0, 0,
|
||||||
0, -1, 0, 0,
|
0, 0, parser.mUnitSize, 0,
|
||||||
1, 0, 0, 0,
|
0, 0, 0, 1);
|
||||||
0, 0, 1, 0,
|
if( !ignoreUpDirection ) {
|
||||||
0, 0, 0, 1);
|
// Convert to Y_UP, if different orientation
|
||||||
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
if( parser.mUpDirection == ColladaParser::UP_X)
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
1, 0, 0, 0,
|
0, -1, 0, 0,
|
||||||
0, 0, 1, 0,
|
1, 0, 0, 0,
|
||||||
0, -1, 0, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
|
else if( parser.mUpDirection == ColladaParser::UP_Z)
|
||||||
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, -1, 0, 0,
|
||||||
|
0, 0, 0, 1);
|
||||||
|
}
|
||||||
// store all meshes
|
// store all meshes
|
||||||
StoreSceneMeshes( pScene);
|
StoreSceneMeshes( pScene);
|
||||||
|
|
||||||
|
@ -325,11 +332,11 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
||||||
|
|
||||||
out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle );
|
out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle );
|
||||||
|
|
||||||
// ... some extension magic. FUCKING COLLADA.
|
// ... some extension magic.
|
||||||
if (srcLight->mOuterAngle == 10e10f)
|
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
|
||||||
{
|
{
|
||||||
// ... some deprecation magic. FUCKING FCOLLADA.
|
// ... some deprecation magic.
|
||||||
if (srcLight->mPenumbraAngle == 10e10f)
|
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
|
||||||
{
|
{
|
||||||
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
|
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
|
||||||
// epsilon chosen to be 0.1
|
// epsilon chosen to be 0.1
|
||||||
|
@ -382,7 +389,7 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
|
||||||
out->mClipPlaneNear = srcCamera->mZNear;
|
out->mClipPlaneNear = srcCamera->mZNear;
|
||||||
|
|
||||||
// ... but for the rest some values are optional
|
// ... but for the rest some values are optional
|
||||||
// and we need to compute the others in any combination. FUCKING COLLADA.
|
// and we need to compute the others in any combination.
|
||||||
if (srcCamera->mAspect != 10e10f)
|
if (srcCamera->mAspect != 10e10f)
|
||||||
out->mAspect = srcCamera->mAspect;
|
out->mAspect = srcCamera->mAspect;
|
||||||
|
|
||||||
|
@ -466,7 +473,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup \"%s\" in geometry \"%s\".") % submesh.mMaterial % mid.mMeshOrController));
|
DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup <%s> in geometry <%s>.") % submesh.mMaterial % mid.mMeshOrController));
|
||||||
if( !mid.mMaterials.empty() )
|
if( !mid.mMaterials.empty() )
|
||||||
meshMaterial = mid.mMaterials.begin()->second.mMatName;
|
meshMaterial = mid.mMaterials.begin()->second.mMatName;
|
||||||
}
|
}
|
||||||
|
@ -514,7 +521,10 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
||||||
|
|
||||||
// assign the material index
|
// assign the material index
|
||||||
dstMesh->mMaterialIndex = matIdx;
|
dstMesh->mMaterialIndex = matIdx;
|
||||||
dstMesh->mName = mid.mMeshOrController;
|
if(dstMesh->mName.length == 0)
|
||||||
|
{
|
||||||
|
dstMesh->mName = mid.mMeshOrController;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,6 +544,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
|
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
|
||||||
{
|
{
|
||||||
aiMesh* dstMesh = new aiMesh;
|
aiMesh* dstMesh = new aiMesh;
|
||||||
|
|
||||||
|
dstMesh->mName = pSrcMesh->mName;
|
||||||
|
|
||||||
// count the vertices addressed by its faces
|
// count the vertices addressed by its faces
|
||||||
const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
|
const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
|
||||||
|
@ -545,7 +557,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
|
std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
|
||||||
pStartVertex + numVertices, dstMesh->mVertices);
|
pStartVertex + numVertices, dstMesh->mVertices);
|
||||||
|
|
||||||
// normals, if given. HACK: (thom) Due to the fucking Collada spec we never
|
// normals, if given. HACK: (thom) Due to the glorious Collada spec we never
|
||||||
// know if we have the same number of normals as there are positions. So we
|
// know if we have the same number of normals as there are positions. So we
|
||||||
// also ignore any vertex attribute if it has a different count
|
// also ignore any vertex attribute if it has a different count
|
||||||
if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
|
if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
|
||||||
|
@ -636,7 +648,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
throw DeadlyImportError( "Data type mismatch while resolving mesh joints");
|
throw DeadlyImportError( "Data type mismatch while resolving mesh joints");
|
||||||
// sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex
|
// sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex
|
||||||
if( pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1)
|
if( pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1)
|
||||||
throw DeadlyImportError( "Unsupported vertex_weight adresssing scheme. Fucking collada spec.");
|
throw DeadlyImportError( "Unsupported vertex_weight addressing scheme. ");
|
||||||
|
|
||||||
// create containers to collect the weights for each bone
|
// create containers to collect the weights for each bone
|
||||||
size_t numBones = jointNames.mStrings.size();
|
size_t numBones = jointNames.mStrings.size();
|
||||||
|
@ -967,7 +979,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
else if( subElement == "Z")
|
else if( subElement == "Z")
|
||||||
entry.mSubElement = 2;
|
entry.mSubElement = 2;
|
||||||
else
|
else
|
||||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement \"%s\". Ignoring") % subElement));
|
DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement <%s>. Ignoring") % subElement));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// no subelement following, transformId is remaining string
|
// no subelement following, transformId is remaining string
|
||||||
|
@ -1445,13 +1457,16 @@ void ColladaLoader::ConvertPath (aiString& ss)
|
||||||
ss.data[ss.length] = 0;
|
ss.data[ss.length] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find and convert all %xyz special chars
|
// find and convert all %xy special chars
|
||||||
char* out = ss.data;
|
char* out = ss.data;
|
||||||
for( const char* it = ss.data; it != ss.data + ss.length; /**/ )
|
for( const char* it = ss.data; it != ss.data + ss.length; /**/ )
|
||||||
{
|
{
|
||||||
if( *it == '%' )
|
if( *it == '%' && (it + 3) < ss.data + ss.length )
|
||||||
{
|
{
|
||||||
size_t nbr = strtoul16( ++it, &it);
|
// separate the number to avoid dragging in chars from behind into the parsing
|
||||||
|
char mychar[3] = { it[1], it[2], 0 };
|
||||||
|
size_t nbr = strtoul16( mychar);
|
||||||
|
it += 3;
|
||||||
*out++ = (char)(nbr & 0xFF);
|
*out++ = (char)(nbr & 0xFF);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
|
@ -234,6 +234,7 @@ protected:
|
||||||
std::vector<aiAnimation*> mAnims;
|
std::vector<aiAnimation*> mAnims;
|
||||||
|
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
|
bool ignoreUpDirection;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -140,7 +140,7 @@ void ColladaParser::ReadContents()
|
||||||
ReadStructure();
|
ReadStructure();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element \"%s\".") % mReader->getNodeName()));
|
DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element <%s>.") % mReader->getNodeName()));
|
||||||
SkipElement();
|
SkipElement();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -240,7 +240,7 @@ void ColladaParser::ReadAssetInfo()
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "asset") != 0)
|
if( strcmp( mReader->getNodeName(), "asset") != 0)
|
||||||
ThrowException( "Expected end of \"asset\" element.");
|
ThrowException( "Expected end of <asset> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ void ColladaParser::ReadAnimationLibrary()
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "library_animations") != 0)
|
if( strcmp( mReader->getNodeName(), "library_animations") != 0)
|
||||||
ThrowException( "Expected end of \"library_animations\" element.");
|
ThrowException( "Expected end of <library_animations> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "animation") != 0)
|
if( strcmp( mReader->getNodeName(), "animation") != 0)
|
||||||
ThrowException( "Expected end of \"animation\" element.");
|
ThrowException( "Expected end of <animation> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +425,7 @@ void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "sampler") != 0)
|
if( strcmp( mReader->getNodeName(), "sampler") != 0)
|
||||||
ThrowException( "Expected end of \"sampler\" element.");
|
ThrowException( "Expected end of <sampler> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ void ColladaParser::ReadControllerLibrary()
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "library_controllers") != 0)
|
if( strcmp( mReader->getNodeName(), "library_controllers") != 0)
|
||||||
ThrowException( "Expected end of \"library_controllers\" element.");
|
ThrowException( "Expected end of <library_controllers> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ void ColladaParser::ReadController( Collada::Controller& pController)
|
||||||
else if( IsElement( "skin"))
|
else if( IsElement( "skin"))
|
||||||
{
|
{
|
||||||
// read the mesh it refers to. According to the spec this could also be another
|
// read the mesh it refers to. According to the spec this could also be another
|
||||||
// controller, but I refuse to implement every bullshit idea they've come up with
|
// controller, but I refuse to implement every single idea they've come up with
|
||||||
int sourceIndex = GetAttribute( "source");
|
int sourceIndex = GetAttribute( "source");
|
||||||
pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1;
|
pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1;
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ void ColladaParser::ReadController( Collada::Controller& pController)
|
||||||
if( strcmp( mReader->getNodeName(), "controller") == 0)
|
if( strcmp( mReader->getNodeName(), "controller") == 0)
|
||||||
break;
|
break;
|
||||||
else if( strcmp( mReader->getNodeName(), "skin") != 0)
|
else if( strcmp( mReader->getNodeName(), "skin") != 0)
|
||||||
ThrowException( "Expected end of \"controller\" element.");
|
ThrowException( "Expected end of <controller> element.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
|
||||||
|
|
||||||
// local URLS always start with a '#'. We don't support global URLs
|
// local URLS always start with a '#'. We don't support global URLs
|
||||||
if( attrSource[0] != '#')
|
if( attrSource[0] != '#')
|
||||||
ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource));
|
ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <joints> data <input> element") % attrSource));
|
||||||
attrSource++;
|
attrSource++;
|
||||||
|
|
||||||
// parse source URL to corresponding source
|
// parse source URL to corresponding source
|
||||||
|
@ -563,7 +563,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
|
||||||
else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0)
|
else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0)
|
||||||
pController.mJointOffsetMatrixSource = attrSource;
|
pController.mJointOffsetMatrixSource = attrSource;
|
||||||
else
|
else
|
||||||
ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in joint data") % attrSemantic));
|
ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <joints> data <input> element") % attrSemantic));
|
||||||
|
|
||||||
// skip inner data, if present
|
// skip inner data, if present
|
||||||
if( !mReader->isEmptyElement())
|
if( !mReader->isEmptyElement())
|
||||||
|
@ -578,7 +578,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "joints") != 0)
|
if( strcmp( mReader->getNodeName(), "joints") != 0)
|
||||||
ThrowException( "Expected end of \"joints\" element.");
|
ThrowException( "Expected end of <joints> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +613,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
|
||||||
|
|
||||||
// local URLS always start with a '#'. We don't support global URLs
|
// local URLS always start with a '#'. We don't support global URLs
|
||||||
if( attrSource[0] != '#')
|
if( attrSource[0] != '#')
|
||||||
ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource));
|
ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <vertex_weights> data <input> element") % attrSource));
|
||||||
channel.mAccessor = attrSource + 1;
|
channel.mAccessor = attrSource + 1;
|
||||||
|
|
||||||
// parse source URL to corresponding source
|
// parse source URL to corresponding source
|
||||||
|
@ -622,7 +622,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
|
||||||
else if( strcmp( attrSemantic, "WEIGHT") == 0)
|
else if( strcmp( attrSemantic, "WEIGHT") == 0)
|
||||||
pController.mWeightInputWeights = channel;
|
pController.mWeightInputWeights = channel;
|
||||||
else
|
else
|
||||||
ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in vertex_weight data") % attrSemantic));
|
ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <vertex_weights> data <input> element") % attrSemantic));
|
||||||
|
|
||||||
// skip inner data, if present
|
// skip inner data, if present
|
||||||
if( !mReader->isEmptyElement())
|
if( !mReader->isEmptyElement())
|
||||||
|
@ -636,7 +636,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
|
||||||
for( std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it)
|
for( std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it)
|
||||||
{
|
{
|
||||||
if( *text == 0)
|
if( *text == 0)
|
||||||
ThrowException( "Out of data while reading vcount");
|
ThrowException( "Out of data while reading <vcount>");
|
||||||
|
|
||||||
*it = strtoul10( text, &text);
|
*it = strtoul10( text, &text);
|
||||||
numWeights += *it;
|
numWeights += *it;
|
||||||
|
@ -656,11 +656,11 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
|
||||||
for( std::vector< std::pair<size_t, size_t> >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it)
|
for( std::vector< std::pair<size_t, size_t> >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it)
|
||||||
{
|
{
|
||||||
if( *text == 0)
|
if( *text == 0)
|
||||||
ThrowException( "Out of data while reading vertex_weights");
|
ThrowException( "Out of data while reading <vertex_weights>");
|
||||||
it->first = strtoul10( text, &text);
|
it->first = strtoul10( text, &text);
|
||||||
SkipSpacesAndLineEnd( &text);
|
SkipSpacesAndLineEnd( &text);
|
||||||
if( *text == 0)
|
if( *text == 0)
|
||||||
ThrowException( "Out of data while reading vertex_weights");
|
ThrowException( "Out of data while reading <vertex_weights>");
|
||||||
it->second = strtoul10( text, &text);
|
it->second = strtoul10( text, &text);
|
||||||
SkipSpacesAndLineEnd( &text);
|
SkipSpacesAndLineEnd( &text);
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "vertex_weights") != 0)
|
if( strcmp( mReader->getNodeName(), "vertex_weights") != 0)
|
||||||
ThrowException( "Expected end of \"vertex_weights\" element.");
|
ThrowException( "Expected end of <vertex_weights> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +712,7 @@ void ColladaParser::ReadImageLibrary()
|
||||||
}
|
}
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||||
if( strcmp( mReader->getNodeName(), "library_images") != 0)
|
if( strcmp( mReader->getNodeName(), "library_images") != 0)
|
||||||
ThrowException( "Expected end of \"library_images\" element.");
|
ThrowException( "Expected end of <library_images> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -838,7 +838,7 @@ void ColladaParser::ReadMaterialLibrary()
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "library_materials") != 0)
|
if( strcmp( mReader->getNodeName(), "library_materials") != 0)
|
||||||
ThrowException( "Expected end of \"library_materials\" element.");
|
ThrowException( "Expected end of <library_materials> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +872,7 @@ void ColladaParser::ReadLightLibrary()
|
||||||
}
|
}
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||||
if( strcmp( mReader->getNodeName(), "library_lights") != 0)
|
if( strcmp( mReader->getNodeName(), "library_lights") != 0)
|
||||||
ThrowException( "Expected end of \"library_lights\" element.");
|
ThrowException( "Expected end of <library_lights> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -911,7 +911,7 @@ void ColladaParser::ReadCameraLibrary()
|
||||||
}
|
}
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||||
if( strcmp( mReader->getNodeName(), "library_cameras") != 0)
|
if( strcmp( mReader->getNodeName(), "library_cameras") != 0)
|
||||||
ThrowException( "Expected end of \"library_cameras\" element.");
|
ThrowException( "Expected end of <library_cameras> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -947,7 +947,7 @@ void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
|
||||||
}
|
}
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||||
if( strcmp( mReader->getNodeName(), "material") != 0)
|
if( strcmp( mReader->getNodeName(), "material") != 0)
|
||||||
ThrowException( "Expected end of \"material\" element.");
|
ThrowException( "Expected end of <material> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1097,9 +1097,6 @@ void ColladaParser::ReadEffectLibrary()
|
||||||
if( IsElement( "effect"))
|
if( IsElement( "effect"))
|
||||||
{
|
{
|
||||||
// read ID. Do I have to repeat my ranting about "optional" attributes?
|
// read ID. Do I have to repeat my ranting about "optional" attributes?
|
||||||
// Alex: .... no, not necessary. Please shut up and leave more space for
|
|
||||||
// me to complain about the fucking Collada spec with its fucking
|
|
||||||
// 'optional' attributes ...
|
|
||||||
int attrID = GetAttribute( "id");
|
int attrID = GetAttribute( "id");
|
||||||
std::string id = mReader->getAttributeValue( attrID);
|
std::string id = mReader->getAttributeValue( attrID);
|
||||||
|
|
||||||
|
@ -1115,7 +1112,7 @@ void ColladaParser::ReadEffectLibrary()
|
||||||
}
|
}
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||||
if( strcmp( mReader->getNodeName(), "library_effects") != 0)
|
if( strcmp( mReader->getNodeName(), "library_effects") != 0)
|
||||||
ThrowException( "Expected end of \"library_effects\" element.");
|
ThrowException( "Expected end of <library_effects> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1136,7 @@ void ColladaParser::ReadEffect( Collada::Effect& pEffect)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "effect") != 0)
|
if( strcmp( mReader->getNodeName(), "effect") != 0)
|
||||||
ThrowException( "Expected end of \"effect\" element.");
|
ThrowException( "Expected end of <effect> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1495,6 +1492,13 @@ void ColladaParser::ReadGeometryLibrary()
|
||||||
// create a mesh and store it in the library under its ID
|
// create a mesh and store it in the library under its ID
|
||||||
Mesh* mesh = new Mesh;
|
Mesh* mesh = new Mesh;
|
||||||
mMeshLibrary[id] = mesh;
|
mMeshLibrary[id] = mesh;
|
||||||
|
|
||||||
|
// read the mesh name if it exists
|
||||||
|
const int nameIndex = TestAttribute("name");
|
||||||
|
if(nameIndex != -1)
|
||||||
|
{
|
||||||
|
mesh->mName = mReader->getAttributeValue(nameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// read on from there
|
// read on from there
|
||||||
ReadGeometry( mesh);
|
ReadGeometry( mesh);
|
||||||
|
@ -1507,7 +1511,7 @@ void ColladaParser::ReadGeometryLibrary()
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "library_geometries") != 0)
|
if( strcmp( mReader->getNodeName(), "library_geometries") != 0)
|
||||||
ThrowException( "Expected end of \"library_geometries\" element.");
|
ThrowException( "Expected end of <library_geometries> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1538,7 +1542,7 @@ void ColladaParser::ReadGeometry( Collada::Mesh* pMesh)
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
{
|
{
|
||||||
if( strcmp( mReader->getNodeName(), "geometry") != 0)
|
if( strcmp( mReader->getNodeName(), "geometry") != 0)
|
||||||
ThrowException( "Expected end of \"geometry\" element.");
|
ThrowException( "Expected end of <geometry> element.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1590,7 +1594,7 @@ void ColladaParser::ReadMesh( Mesh* pMesh)
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else should be punished
|
// everything else should be punished
|
||||||
ThrowException( "Expected end of \"mesh\" element.");
|
ThrowException( "Expected end of <mesh> element.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1613,7 +1617,7 @@ void ColladaParser::ReadSource()
|
||||||
}
|
}
|
||||||
else if( IsElement( "technique_common"))
|
else if( IsElement( "technique_common"))
|
||||||
{
|
{
|
||||||
// I don't fucking care for your profiles bullshit
|
// I don't care for your profiles
|
||||||
}
|
}
|
||||||
else if( IsElement( "accessor"))
|
else if( IsElement( "accessor"))
|
||||||
{
|
{
|
||||||
|
@ -1637,7 +1641,7 @@ void ColladaParser::ReadSource()
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else should be punished
|
// everything else should be punished
|
||||||
ThrowException( "Expected end of \"source\" element.");
|
ThrowException( "Expected end of <source> element.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1716,7 +1720,7 @@ void ColladaParser::ReadAccessor( const std::string& pID)
|
||||||
int attrSource = GetAttribute( "source");
|
int attrSource = GetAttribute( "source");
|
||||||
const char* source = mReader->getAttributeValue( attrSource);
|
const char* source = mReader->getAttributeValue( attrSource);
|
||||||
if( source[0] != '#')
|
if( source[0] != '#')
|
||||||
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
|
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <accessor> element.") % source));
|
||||||
int attrCount = GetAttribute( "count");
|
int attrCount = GetAttribute( "count");
|
||||||
unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
|
unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
|
||||||
int attrOffset = TestAttribute( "offset");
|
int attrOffset = TestAttribute( "offset");
|
||||||
|
@ -1901,7 +1905,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||||
for( unsigned int a = 0; a < numPrimitives; a++)
|
for( unsigned int a = 0; a < numPrimitives; a++)
|
||||||
{
|
{
|
||||||
if( *content == 0)
|
if( *content == 0)
|
||||||
ThrowException( "Expected more values while reading vcount contents.");
|
ThrowException( "Expected more values while reading <vcount> contents.");
|
||||||
// read a number
|
// read a number
|
||||||
vcount.push_back( (size_t) strtoul10( content, &content));
|
vcount.push_back( (size_t) strtoul10( content, &content));
|
||||||
// skip whitespace after it
|
// skip whitespace after it
|
||||||
|
@ -1949,7 +1953,7 @@ void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
|
||||||
int attrSource = GetAttribute( "source");
|
int attrSource = GetAttribute( "source");
|
||||||
const char* source = mReader->getAttributeValue( attrSource);
|
const char* source = mReader->getAttributeValue( attrSource);
|
||||||
if( source[0] != '#')
|
if( source[0] != '#')
|
||||||
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
|
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <input> element.") % source));
|
||||||
channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
|
channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
|
||||||
|
|
||||||
// read index offset, if per-index <input>
|
// read index offset, if per-index <input>
|
||||||
|
@ -1963,7 +1967,7 @@ void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
|
||||||
if(attrSet > -1){
|
if(attrSet > -1){
|
||||||
attrSet = mReader->getAttributeValueAsInt( attrSet);
|
attrSet = mReader->getAttributeValueAsInt( attrSet);
|
||||||
if(attrSet < 0)
|
if(attrSet < 0)
|
||||||
ThrowException( boost::str( boost::format( "Invalid index \"%i\" for set attribute") % (attrSet)));
|
ThrowException( boost::str( boost::format( "Invalid index \"%i\" in set attribute of <input> element") % (attrSet)));
|
||||||
|
|
||||||
channel.mIndex = attrSet;
|
channel.mIndex = attrSet;
|
||||||
}
|
}
|
||||||
|
@ -2581,18 +2585,18 @@ void ColladaParser::ReadScene()
|
||||||
{
|
{
|
||||||
// should be the first and only occurence
|
// should be the first and only occurence
|
||||||
if( mRootNode)
|
if( mRootNode)
|
||||||
ThrowException( "Invalid scene containing multiple root nodes");
|
ThrowException( "Invalid scene containing multiple root nodes in <instance_visual_scene> element");
|
||||||
|
|
||||||
// read the url of the scene to instance. Should be of format "#some_name"
|
// read the url of the scene to instance. Should be of format "#some_name"
|
||||||
int urlIndex = GetAttribute( "url");
|
int urlIndex = GetAttribute( "url");
|
||||||
const char* url = mReader->getAttributeValue( urlIndex);
|
const char* url = mReader->getAttributeValue( urlIndex);
|
||||||
if( url[0] != '#')
|
if( url[0] != '#')
|
||||||
ThrowException( "Unknown reference format");
|
ThrowException( "Unknown reference format in <instance_visual_scene> element");
|
||||||
|
|
||||||
// find the referred scene, skip the leading #
|
// find the referred scene, skip the leading #
|
||||||
NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1);
|
NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1);
|
||||||
if( sit == mNodeLibrary.end())
|
if( sit == mNodeLibrary.end())
|
||||||
ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\".");
|
ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element.");
|
||||||
mRootNode = sit->second;
|
mRootNode = sit->second;
|
||||||
} else {
|
} else {
|
||||||
SkipElement();
|
SkipElement();
|
||||||
|
@ -2644,14 +2648,14 @@ void ColladaParser::TestOpening( const char* pName)
|
||||||
{
|
{
|
||||||
// read element start
|
// read element start
|
||||||
if( !mReader->read())
|
if( !mReader->read())
|
||||||
ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of <%s> element.") % pName));
|
||||||
// whitespace in front is ok, just read again if found
|
// whitespace in front is ok, just read again if found
|
||||||
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
||||||
if( !mReader->read())
|
if( !mReader->read())
|
||||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of <%s> element.") % pName));
|
||||||
|
|
||||||
if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
|
if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
|
||||||
ThrowException( boost::str( boost::format( "Expected start of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Expected start of <%s> element.") % pName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -2664,15 +2668,15 @@ void ColladaParser::TestClosing( const char* pName)
|
||||||
|
|
||||||
// if not, read some more
|
// if not, read some more
|
||||||
if( !mReader->read())
|
if( !mReader->read())
|
||||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName));
|
||||||
// whitespace in front is ok, just read again if found
|
// whitespace in front is ok, just read again if found
|
||||||
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
||||||
if( !mReader->read())
|
if( !mReader->read())
|
||||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName));
|
||||||
|
|
||||||
// but this has the be the closing tag, or we're lost
|
// but this has the be the closing tag, or we're lost
|
||||||
if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
|
if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
|
||||||
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName));
|
ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % pName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -2684,7 +2688,7 @@ int ColladaParser::GetAttribute( const char* pAttr) const
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
// attribute not found -> throw an exception
|
// attribute not found -> throw an exception
|
||||||
ThrowException( boost::str( boost::format( "Expected attribute \"%s\" at element \"%s\".") % pAttr % mReader->getNodeName()));
|
ThrowException( boost::str( boost::format( "Expected attribute \"%s\" for element <%s>.") % pAttr % mReader->getNodeName()));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
#include "BaseProcess.h"
|
#include "BaseProcess.h"
|
||||||
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
||||||
|
|
||||||
|
#include "JoinVerticesProcess.h"
|
||||||
#include "MakeVerboseFormat.h"
|
#include "MakeVerboseFormat.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
||||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
||||||
|
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
||||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
|
void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
|
||||||
|
|
||||||
|
@ -85,13 +87,17 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj),
|
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||||
|
aiProcess_GenNormals /*| aiProcess_PreTransformVertices */),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
|
Exporter::ExportFormatEntry( "stlb", "Stereolithography(binary)", "stlb" , &ExportSceneSTLBinary,
|
||||||
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
|
),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
||||||
|
@ -196,7 +202,7 @@ bool Exporter :: IsDefaultIOHandler() const
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
|
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int )
|
||||||
{
|
{
|
||||||
if (pimpl->blob) {
|
if (pimpl->blob) {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
|
@ -259,6 +265,7 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
|
|
||||||
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
||||||
// we need to run the MakeVerboseFormat step first.
|
// we need to run the MakeVerboseFormat step first.
|
||||||
|
bool must_join_again = false;
|
||||||
if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
||||||
|
|
||||||
bool verbosify = false;
|
bool verbosify = false;
|
||||||
|
@ -276,6 +283,10 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
|
|
||||||
MakeVerboseFormatProcess proc;
|
MakeVerboseFormatProcess proc;
|
||||||
proc.Execute(scenecopy.get());
|
proc.Execute(scenecopy.get());
|
||||||
|
|
||||||
|
if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
||||||
|
must_join_again = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +331,11 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
privOut->mPPStepsApplied |= pp;
|
privOut->mPPStepsApplied |= pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(must_join_again) {
|
||||||
|
JoinVerticesProcess proc;
|
||||||
|
proc.Execute(scenecopy.get());
|
||||||
|
}
|
||||||
|
|
||||||
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
||||||
}
|
}
|
||||||
catch (DeadlyExportError& err) {
|
catch (DeadlyExportError& err) {
|
||||||
|
|
|
@ -232,7 +232,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
|
|
||||||
// compute length based on type and check against the stored value
|
// compute length based on type and check against the stored value
|
||||||
if(encoding == 0) {
|
if(encoding == 0) {
|
||||||
uint32_t stride;
|
uint32_t stride = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -248,6 +248,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
};
|
||||||
|
ai_assert(stride > 0);
|
||||||
if(length * stride != comp_len) {
|
if(length * stride != comp_len) {
|
||||||
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
||||||
}
|
}
|
||||||
|
@ -380,7 +381,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t offset = 0x1b;
|
//uint32_t offset = 0x1b;
|
||||||
|
|
||||||
const char* cursor = input + 0x1b;
|
const char* cursor = input + 0x1b;
|
||||||
|
|
||||||
|
|
|
@ -97,9 +97,9 @@ public:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Converter(aiScene* out, const Document& doc)
|
Converter(aiScene* out, const Document& doc)
|
||||||
: out(out)
|
: defaultMaterialIndex()
|
||||||
|
, out(out)
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
, defaultMaterialIndex()
|
|
||||||
{
|
{
|
||||||
// animations need to be converted first since this will
|
// animations need to be converted first since this will
|
||||||
// populate the node_anim_chain_bits map, which is needed
|
// populate the node_anim_chain_bits map, which is needed
|
||||||
|
@ -419,6 +419,8 @@ private:
|
||||||
return "Scaling";
|
return "Scaling";
|
||||||
case TransformationComp_ScalingPivotInverse:
|
case TransformationComp_ScalingPivotInverse:
|
||||||
return "ScalingPivotInverse";
|
return "ScalingPivotInverse";
|
||||||
|
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
@ -454,6 +456,8 @@ private:
|
||||||
return "Lcl Scaling";
|
return "Lcl Scaling";
|
||||||
case TransformationComp_ScalingPivotInverse:
|
case TransformationComp_ScalingPivotInverse:
|
||||||
return "ScalingPivotInverse";
|
return "ScalingPivotInverse";
|
||||||
|
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
@ -543,6 +547,10 @@ private:
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert((order[0] >= 0) && (order[0] <= 2));
|
||||||
|
ai_assert((order[1] >= 0) && (order[1] <= 2));
|
||||||
|
ai_assert((order[2] >= 0) && (order[2] <= 2));
|
||||||
|
|
||||||
if(!is_id[order[0]]) {
|
if(!is_id[order[0]]) {
|
||||||
out = temp[order[0]];
|
out = temp[order[0]];
|
||||||
|
@ -1167,7 +1175,6 @@ private:
|
||||||
ai_assert(cluster);
|
ai_assert(cluster);
|
||||||
|
|
||||||
const WeightIndexArray& indices = cluster->GetIndices();
|
const WeightIndexArray& indices = cluster->GetIndices();
|
||||||
const WeightArray& weights = cluster->GetWeights();
|
|
||||||
|
|
||||||
if(indices.empty()) {
|
if(indices.empty()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1194,7 +1201,7 @@ private:
|
||||||
count_out_indices.push_back(0);
|
count_out_indices.push_back(0);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < count; ++i) {
|
for(unsigned int i = 0; i < count; ++i) {
|
||||||
if (no_mat_check || mats[geo.FaceForVertexIndex(out_idx[i])] == materialIndex) {
|
if (no_mat_check || static_cast<size_t>(mats[geo.FaceForVertexIndex(out_idx[i])]) == materialIndex) {
|
||||||
|
|
||||||
if (index_out_indices.back() == no_index_sentinel) {
|
if (index_out_indices.back() == no_index_sentinel) {
|
||||||
index_out_indices.back() = out_indices.size();
|
index_out_indices.back() = out_indices.size();
|
||||||
|
@ -1608,6 +1615,9 @@ private:
|
||||||
|
|
||||||
case FileGlobalSettings::FrameRate_CUSTOM:
|
case FileGlobalSettings::FrameRate_CUSTOM:
|
||||||
return customFPSVal;
|
return customFPSVal;
|
||||||
|
|
||||||
|
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
@ -1838,7 +1848,7 @@ private:
|
||||||
}}
|
}}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const AnimationCurveNode* curve_node;
|
const AnimationCurveNode* curve_node = NULL;
|
||||||
BOOST_FOREACH(const AnimationCurveNode* node, curves) {
|
BOOST_FOREACH(const AnimationCurveNode* node, curves) {
|
||||||
ai_assert(node);
|
ai_assert(node);
|
||||||
|
|
||||||
|
|
|
@ -231,8 +231,8 @@ Object::~Object()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
FileGlobalSettings::FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props)
|
FileGlobalSettings::FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props)
|
||||||
: doc(doc)
|
: props(props)
|
||||||
, props(props)
|
, doc(doc)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||||
|
|
||||||
for (size_t i = 0; i < c; ++i) {
|
for (size_t i = 0; i < c; ++i) {
|
||||||
ai_assert(classnames[i]);
|
ai_assert(classnames[i]);
|
||||||
if(std::distance(key.begin(),key.end()) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
|
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
|
||||||
obtype = NULL;
|
obtype = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ namespace Util {
|
||||||
|
|
||||||
|
|
||||||
/* DOM/Parse error reporting - does not return */
|
/* DOM/Parse error reporting - does not return */
|
||||||
void DOMError(const std::string& message, const Token& token);
|
AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
|
||||||
void DOMError(const std::string& message, const Element* element = NULL);
|
AI_WONT_RETURN void DOMError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// does return
|
// does return
|
||||||
void DOMWarning(const std::string& message, const Token& token);
|
void DOMWarning(const std::string& message, const Token& token);
|
||||||
|
|
|
@ -51,13 +51,13 @@ namespace FBX {
|
||||||
struct ImportSettings
|
struct ImportSettings
|
||||||
{
|
{
|
||||||
ImportSettings()
|
ImportSettings()
|
||||||
: readAllLayers(true)
|
: strictMode(true)
|
||||||
|
, readAllLayers(true)
|
||||||
, readAllMaterials()
|
, readAllMaterials()
|
||||||
, readMaterials(true)
|
, readMaterials(true)
|
||||||
, readCameras(true)
|
, readCameras(true)
|
||||||
, readLights(true)
|
, readLights(true)
|
||||||
, readAnimations(true)
|
, readAnimations(true)
|
||||||
, strictMode(true)
|
|
||||||
, readWeights(true)
|
, readWeights(true)
|
||||||
, preservePivots(true)
|
, preservePivots(true)
|
||||||
, optimizeEmptyAnimationCurves(true)
|
, optimizeEmptyAnimationCurves(true)
|
||||||
|
|
|
@ -512,7 +512,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
||||||
ai_assert(data + comp_len == end);
|
ai_assert(data + comp_len == end);
|
||||||
|
|
||||||
// determine the length of the uncompressed data by looking at the type signature
|
// determine the length of the uncompressed data by looking at the type signature
|
||||||
uint32_t stride;
|
uint32_t stride = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
|
@ -72,6 +72,9 @@ const char* TokenTypeString(TokenType t)
|
||||||
|
|
||||||
case TokenType_KEY:
|
case TokenType_KEY:
|
||||||
return "TOK_KEY";
|
return "TOK_KEY";
|
||||||
|
|
||||||
|
case TokenType_BINARY_DATA:
|
||||||
|
return "TOK_BINARY_DATA";
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
|
|
@ -245,7 +245,7 @@ bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, cons
|
||||||
// directly on the vertex between two segments.
|
// directly on the vertex between two segments.
|
||||||
if (!intersected_boundary_points.empty() && intersected_boundary_segments.back()==i-1 ) {
|
if (!intersected_boundary_points.empty() && intersected_boundary_segments.back()==i-1 ) {
|
||||||
const IfcVector3 diff = intersected_boundary_points.back() - p;
|
const IfcVector3 diff = intersected_boundary_points.back() - p;
|
||||||
if(IfcVector3((diff.x, diff.y)).SquareLength() < 1e-7) {
|
if(IfcVector2(diff.x, diff.y).SquareLength() < 1e-7) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,8 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBounded
|
||||||
unsigned int newcount = 0;
|
unsigned int newcount = 0;
|
||||||
bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts);
|
bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts);
|
||||||
|
|
||||||
size_t last_intersected_boundary_segment;
|
// used any more?
|
||||||
|
//size_t last_intersected_boundary_segment;
|
||||||
IfcVector3 last_intersected_boundary_point;
|
IfcVector3 last_intersected_boundary_point;
|
||||||
|
|
||||||
bool extra_point_flag = false;
|
bool extra_point_flag = false;
|
||||||
|
|
|
@ -137,8 +137,6 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
|
|
||||||
const size_t outer_polygon_size = *outer_polygon_it;
|
const size_t outer_polygon_size = *outer_polygon_it;
|
||||||
const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
|
const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
|
||||||
const IfcVector3& master_normal_norm = IfcVector3(master_normal).Normalize();
|
|
||||||
|
|
||||||
|
|
||||||
// Generate fake openings to meet the interface for the quadrulate
|
// Generate fake openings to meet the interface for the quadrulate
|
||||||
// algorithm. It boils down to generating small boxes given the
|
// algorithm. It boils down to generating small boxes given the
|
||||||
|
@ -329,8 +327,7 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<IfcVector3>& in = result.verts;
|
const std::vector<IfcVector3>& in = result.verts;
|
||||||
const size_t size=in.size();
|
|
||||||
|
|
||||||
const unsigned int cnt_segments = 16;
|
const unsigned int cnt_segments = 16;
|
||||||
const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments;
|
const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments;
|
||||||
|
|
||||||
|
@ -476,12 +473,12 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||||
IfcVector3 nor;
|
IfcVector3 nor;
|
||||||
|
|
||||||
// The input polygon is arbitrarily shaped, therefore we might need some tries
|
// The input polygon is arbitrarily shaped, therefore we might need some tries
|
||||||
// until we find a suitable normal. Note that Newells algorithm would give
|
// until we find a suitable normal. Note that Newell's algorithm would give
|
||||||
// a more robust result, but this variant also gives us a suitable first
|
// a more robust result, but this variant also gives us a suitable first
|
||||||
// axis for the 2D coordinate space on the polygon plane, exploiting the
|
// axis for the 2D coordinate space on the polygon plane, exploiting the
|
||||||
// fact that the input polygon is nearly always a quad.
|
// fact that the input polygon is nearly always a quad.
|
||||||
bool done = false;
|
bool done = false;
|
||||||
size_t base = 0, i, j;
|
size_t i, j;
|
||||||
for (i = 0; !done && i < s-2; done || ++i) {
|
for (i = 0; !done && i < s-2; done || ++i) {
|
||||||
for (j = i+1; j < s-1; ++j) {
|
for (j = i+1; j < s-1; ++j) {
|
||||||
nor = -((out[i]-any_point)^(out[j]-any_point));
|
nor = -((out[i]-any_point)^(out[j]-any_point));
|
||||||
|
|
|
@ -48,7 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
#include "../contrib/unzip/unzip.h"
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
|
||||||
|
# include "../contrib/unzip/unzip.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "IFCLoader.h"
|
#include "IFCLoader.h"
|
||||||
#include "STEPFileReader.h"
|
#include "STEPFileReader.h"
|
||||||
|
@ -169,8 +171,10 @@ void IFCImporter::InternReadFile( const std::string& pFile,
|
||||||
ThrowException("Could not open file for reading");
|
ThrowException("Could not open file for reading");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if this is a ifczip file, decompress its contents first
|
// if this is a ifczip file, decompress its contents first
|
||||||
if(GetExtension(pFile) == "ifczip") {
|
if(GetExtension(pFile) == "ifczip") {
|
||||||
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
|
||||||
unzFile zip = unzOpen( pFile.c_str() );
|
unzFile zip = unzOpen( pFile.c_str() );
|
||||||
if(zip == NULL) {
|
if(zip == NULL) {
|
||||||
ThrowException("Could not open ifczip file for reading, unzip failed");
|
ThrowException("Could not open ifczip file for reading, unzip failed");
|
||||||
|
@ -188,32 +192,50 @@ void IFCImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// search file (same name as the IFCZIP except for the file extension) and place file pointer there
|
// search file (same name as the IFCZIP except for the file extension) and place file pointer there
|
||||||
if ( unzLocateFile( zip, fileName.c_str(), 0 ) == UNZ_OK )
|
|
||||||
{
|
if(UNZ_OK == unzGoToFirstFile(zip)) {
|
||||||
// get file size, etc.
|
do {
|
||||||
unz_file_info fileInfo;
|
//
|
||||||
unzGetCurrentFileInfo( zip , &fileInfo, 0, 0, 0, 0, 0, 0 );
|
|
||||||
|
|
||||||
uint8_t* buff = new uint8_t[fileInfo.uncompressed_size];
|
// get file size, etc.
|
||||||
|
unz_file_info fileInfo;
|
||||||
|
char filename[256];
|
||||||
|
unzGetCurrentFileInfo( zip , &fileInfo, filename, sizeof(filename), 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
if (GetExtension(filename) != "ifc") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LogInfo("Decompressing IFCZIP file");
|
uint8_t* buff = new uint8_t[fileInfo.uncompressed_size];
|
||||||
|
|
||||||
unzOpenCurrentFile( zip );
|
LogInfo("Decompressing IFCZIP file");
|
||||||
const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size);
|
|
||||||
size_t filesize = fileInfo.uncompressed_size;
|
unzOpenCurrentFile( zip );
|
||||||
if ( ret < 0 || size_t(ret) != filesize )
|
const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size);
|
||||||
{
|
size_t filesize = fileInfo.uncompressed_size;
|
||||||
delete[] buff;
|
if ( ret < 0 || size_t(ret) != filesize )
|
||||||
ThrowException("Failed to decompress IFC ZIP file");
|
{
|
||||||
}
|
delete[] buff;
|
||||||
unzCloseCurrentFile( zip );
|
ThrowException("Failed to decompress IFC ZIP file");
|
||||||
stream.reset(new MemoryIOStream(buff,fileInfo.uncompressed_size,true));
|
}
|
||||||
|
unzCloseCurrentFile( zip );
|
||||||
|
stream.reset(new MemoryIOStream(buff,fileInfo.uncompressed_size,true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) {
|
||||||
|
ThrowException("Found no IFC file member in IFCZIP file (1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ThrowException("Found no IFC file member in IFCZIP file");
|
ThrowException("Found no IFC file member in IFCZIP file (2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
unzClose(zip);
|
unzClose(zip);
|
||||||
|
#else
|
||||||
|
ThrowException("Could not open ifczip file for reading, assimp was built without ifczip support");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::scoped_ptr<STEP::DB> db(STEP::ReadFileHeader(stream));
|
boost::scoped_ptr<STEP::DB> db(STEP::ReadFileHeader(stream));
|
||||||
|
@ -244,7 +266,7 @@ void IFCImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// tell the reader for which types we need to simulate STEPs reverse indices
|
// tell the reader for which types we need to simulate STEPs reverse indices
|
||||||
static const char* const inverse_indices_to_track[] = {
|
static const char* const inverse_indices_to_track[] = {
|
||||||
"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcstyleditem"
|
"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcreldefinesbyproperties", "ifcpropertyset", "ifcstyleditem"
|
||||||
};
|
};
|
||||||
|
|
||||||
// feed the IFC schema into the reader and pre-parse all lines
|
// feed the IFC schema into the reader and pre-parse all lines
|
||||||
|
@ -506,7 +528,7 @@ struct RateRepresentationPredicate {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// give strong preference to extruded geometry
|
// give strong preference to extruded geometry.
|
||||||
if (r == "SweptSolid") {
|
if (r == "SweptSolid") {
|
||||||
return -10;
|
return -10;
|
||||||
}
|
}
|
||||||
|
@ -577,6 +599,86 @@ void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector<
|
||||||
AssignAddedMeshes(meshes,nd,conv);
|
AssignAddedMeshes(meshes,nd,conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef std::map<std::string, std::string> Metadata;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ProcessMetadata(const ListOf< Lazy< IfcProperty >, 1, 0 >& set, ConversionData& conv, Metadata& properties,
|
||||||
|
const std::string& prefix = "",
|
||||||
|
unsigned int nest = 0)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const IfcProperty& property, set) {
|
||||||
|
const std::string& key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
|
||||||
|
if (const IfcPropertySingleValue* const singleValue = property.ToPtr<IfcPropertySingleValue>()) {
|
||||||
|
if (singleValue->NominalValue) {
|
||||||
|
if (const EXPRESS::STRING* str = singleValue->NominalValue.Get()->ToPtr<EXPRESS::STRING>()) {
|
||||||
|
std::string value = static_cast<std::string>(*str);
|
||||||
|
properties[key]=value;
|
||||||
|
}
|
||||||
|
else if (const EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::REAL>()) {
|
||||||
|
float value = static_cast<float>(*val);
|
||||||
|
std::stringstream s;
|
||||||
|
s << value;
|
||||||
|
properties[key]=s.str();
|
||||||
|
}
|
||||||
|
else if (const EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::INTEGER>()) {
|
||||||
|
int64_t value = static_cast<int64_t>(*val);
|
||||||
|
std::stringstream s;
|
||||||
|
s << value;
|
||||||
|
properties[key]=s.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (const IfcPropertyListValue* const listValue = property.ToPtr<IfcPropertyListValue>()) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "[";
|
||||||
|
unsigned index=0;
|
||||||
|
BOOST_FOREACH(const IfcValue::Out& v, listValue->ListValues) {
|
||||||
|
if (!v) continue;
|
||||||
|
if (const EXPRESS::STRING* str = v->ToPtr<EXPRESS::STRING>()) {
|
||||||
|
std::string value = static_cast<std::string>(*str);
|
||||||
|
ss << "'" << value << "'";
|
||||||
|
}
|
||||||
|
else if (const EXPRESS::REAL* val = v->ToPtr<EXPRESS::REAL>()) {
|
||||||
|
float value = static_cast<float>(*val);
|
||||||
|
ss << value;
|
||||||
|
}
|
||||||
|
else if (const EXPRESS::INTEGER* val = v->ToPtr<EXPRESS::INTEGER>()) {
|
||||||
|
int64_t value = static_cast<int64_t>(*val);
|
||||||
|
ss << value;
|
||||||
|
}
|
||||||
|
if (index+1<listValue->ListValues.size()) {
|
||||||
|
ss << ",";
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
ss << "]";
|
||||||
|
properties[key]=ss.str();
|
||||||
|
}
|
||||||
|
else if (const IfcComplexProperty* const complexProp = property.ToPtr<IfcComplexProperty>()) {
|
||||||
|
if(nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities
|
||||||
|
IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
properties[key]="";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties)
|
||||||
|
{
|
||||||
|
if (const IfcRelDefinesByProperties* const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<IfcRelDefinesByProperties>()) {
|
||||||
|
if (const IfcPropertySet* const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<IfcPropertySet>()) {
|
||||||
|
ProcessMetadata(set->HasProperties, conv, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, ConversionData& conv, std::vector<TempOpening>* collect_openings = NULL)
|
aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, ConversionData& conv, std::vector<TempOpening>* collect_openings = NULL)
|
||||||
{
|
{
|
||||||
|
@ -602,6 +704,42 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
nd->mName.Set(el.GetClassName()+"_"+(el.Name?el.Name.Get():"Unnamed")+"_"+el.GlobalId);
|
nd->mName.Set(el.GetClassName()+"_"+(el.Name?el.Name.Get():"Unnamed")+"_"+el.GlobalId);
|
||||||
nd->mParent = parent;
|
nd->mParent = parent;
|
||||||
|
|
||||||
|
conv.already_processed.insert(el.GetID());
|
||||||
|
|
||||||
|
// check for node metadata
|
||||||
|
STEP::DB::RefMapRange children = refs.equal_range(el.GetID());
|
||||||
|
if (children.first!=refs.end()) {
|
||||||
|
Metadata properties;
|
||||||
|
if (children.first==children.second) {
|
||||||
|
// handles single property set
|
||||||
|
ProcessMetadata((*children.first).second, conv, properties);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// handles multiple property sets (currently all property sets are merged,
|
||||||
|
// which may not be the best solution in the long run)
|
||||||
|
for (STEP::DB::RefMap::const_iterator it=children.first; it!=children.second; ++it) {
|
||||||
|
ProcessMetadata((*it).second, conv, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!properties.empty()) {
|
||||||
|
aiMetadata* data = new aiMetadata();
|
||||||
|
data->mNumProperties = properties.size();
|
||||||
|
data->mKeys = new aiString*[data->mNumProperties]();
|
||||||
|
data->mValues = new aiString*[data->mNumProperties]();
|
||||||
|
|
||||||
|
unsigned int i = 0;
|
||||||
|
BOOST_FOREACH(const Metadata::value_type& kv, properties) {
|
||||||
|
data->mKeys[i] = new aiString(kv.first);
|
||||||
|
if (kv.second.length() > 0) {
|
||||||
|
data->mValues[i] = new aiString(kv.second);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
nd->mMetaData = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(el.ObjectPlacement) {
|
if(el.ObjectPlacement) {
|
||||||
ResolveObjectPlacement(nd->mTransformation,el.ObjectPlacement.Get(),conv);
|
ResolveObjectPlacement(nd->mTransformation,el.ObjectPlacement.Get(),conv);
|
||||||
}
|
}
|
||||||
|
@ -620,15 +758,24 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
STEP::DB::RefMapRange range = refs.equal_range(el.GetID());
|
STEP::DB::RefMapRange range = refs.equal_range(el.GetID());
|
||||||
|
|
||||||
for(STEP::DB::RefMapRange range2 = range; range2.first != range.second; ++range2.first) {
|
for(STEP::DB::RefMapRange range2 = range; range2.first != range.second; ++range2.first) {
|
||||||
|
// skip over meshes that have already been processed before. This is strictly necessary
|
||||||
|
// because the reverse indices also include references contained in argument lists and
|
||||||
|
// therefore every element has a back-reference hold by its parent.
|
||||||
|
if (conv.already_processed.find((*range2.first).second) != conv.already_processed.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const STEP::LazyObject& obj = conv.db.MustGetObject((*range2.first).second);
|
const STEP::LazyObject& obj = conv.db.MustGetObject((*range2.first).second);
|
||||||
|
|
||||||
// handle regularly-contained elements
|
// handle regularly-contained elements
|
||||||
if(const IfcRelContainedInSpatialStructure* const cont = obj->ToPtr<IfcRelContainedInSpatialStructure>()) {
|
if(const IfcRelContainedInSpatialStructure* const cont = obj->ToPtr<IfcRelContainedInSpatialStructure>()) {
|
||||||
|
if(cont->RelatingStructure->GetID() != el.GetID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
BOOST_FOREACH(const IfcProduct& pro, cont->RelatedElements) {
|
BOOST_FOREACH(const IfcProduct& pro, cont->RelatedElements) {
|
||||||
if(const IfcOpeningElement* const open = pro.ToPtr<IfcOpeningElement>()) {
|
if(const IfcOpeningElement* const open = pro.ToPtr<IfcOpeningElement>()) {
|
||||||
// IfcOpeningElement is handled below. Sadly we can't use it here as is:
|
// IfcOpeningElement is handled below. Sadly we can't use it here as is:
|
||||||
// The docs say that opening elements are USUALLY attached to building storeys
|
// The docs say that opening elements are USUALLY attached to building storey,
|
||||||
// but we want them for the building elements to which they belong to.
|
// but we want them for the building elements to which they belong.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +826,14 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;range.first != range.second; ++range.first) {
|
for(;range.first != range.second; ++range.first) {
|
||||||
|
// see note in loop above
|
||||||
|
if (conv.already_processed.find((*range.first).second) != conv.already_processed.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
|
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
|
||||||
|
if(aggr->RelatingObject->GetID() != el.GetID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// move aggregate elements to a separate node since they are semantically different than elements that are just 'contained'
|
// move aggregate elements to a separate node since they are semantically different than elements that are just 'contained'
|
||||||
std::auto_ptr<aiNode> nd_aggr(new aiNode());
|
std::auto_ptr<aiNode> nd_aggr(new aiNode());
|
||||||
|
@ -725,6 +879,8 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert(conv.already_processed.find(el.GetID()) != conv.already_processed.end());
|
||||||
|
conv.already_processed.erase(conv.already_processed.find(el.GetID()));
|
||||||
return nd.release();
|
return nd.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -603,7 +603,6 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||||
const IfcVector2& m0, const IfcVector2& m1,
|
const IfcVector2& m0, const IfcVector2& m1,
|
||||||
IfcVector2& out0, IfcVector2& out1)
|
IfcVector2& out0, IfcVector2& out1)
|
||||||
{
|
{
|
||||||
const IfcVector2& m0_to_m1 = m1 - m0;
|
|
||||||
const IfcVector2& n0_to_n1 = n1 - n0;
|
const IfcVector2& n0_to_n1 = n1 - n0;
|
||||||
|
|
||||||
const IfcVector2& n0_to_m0 = m0 - n0;
|
const IfcVector2& n0_to_m0 = m0 - n0;
|
||||||
|
@ -898,14 +897,13 @@ size_t CloseWindows(ContourVector& contours,
|
||||||
|
|
||||||
ai_assert((*it).skiplist.size() == (*it).contour.size());
|
ai_assert((*it).skiplist.size() == (*it).contour.size());
|
||||||
|
|
||||||
SkipList::const_iterator skipbegin = (*it).skiplist.begin(), skipend = (*it).skiplist.end();
|
SkipList::const_iterator skipbegin = (*it).skiplist.begin();
|
||||||
|
|
||||||
curmesh.verts.reserve(curmesh.verts.size() + (*it).contour.size() * 4);
|
curmesh.verts.reserve(curmesh.verts.size() + (*it).contour.size() * 4);
|
||||||
curmesh.vertcnt.reserve(curmesh.vertcnt.size() + (*it).contour.size());
|
curmesh.vertcnt.reserve(curmesh.vertcnt.size() + (*it).contour.size());
|
||||||
|
|
||||||
// XXX this algorithm is really a bit inefficient - both in terms
|
// XXX this algorithm is really a bit inefficient - both in terms
|
||||||
// of constant factor and of asymptotic runtime.
|
// of constant factor and of asymptotic runtime.
|
||||||
size_t vstart = curmesh.verts.size();
|
|
||||||
std::vector<bool>::const_iterator skipit = skipbegin;
|
std::vector<bool>::const_iterator skipit = skipbegin;
|
||||||
|
|
||||||
IfcVector3 start0;
|
IfcVector3 start0;
|
||||||
|
@ -991,10 +989,10 @@ size_t CloseWindows(ContourVector& contours,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
BOOST_FOREACH(TempOpening* opening, refs) {
|
BOOST_FOREACH(TempOpening* opening, refs) {
|
||||||
//opening->wallPoints.clear();
|
//opening->wallPoints.clear();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1146,7 +1144,6 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
bool generate_connection_geometry,
|
bool generate_connection_geometry,
|
||||||
const IfcVector3& wall_extrusion_axis)
|
const IfcVector3& wall_extrusion_axis)
|
||||||
{
|
{
|
||||||
std::vector<IfcVector3>& out = curmesh.verts;
|
|
||||||
OpeningRefVector contours_to_openings;
|
OpeningRefVector contours_to_openings;
|
||||||
|
|
||||||
// Try to derive a solid base plane within the current surface for use as
|
// Try to derive a solid base plane within the current surface for use as
|
||||||
|
@ -1175,7 +1172,6 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
IfcVector3 wall_extrusion_axis_norm = wall_extrusion_axis;
|
IfcVector3 wall_extrusion_axis_norm = wall_extrusion_axis;
|
||||||
wall_extrusion_axis_norm.Normalize();
|
wall_extrusion_axis_norm.Normalize();
|
||||||
|
|
||||||
size_t c = 0;
|
|
||||||
BOOST_FOREACH(TempOpening& opening,openings) {
|
BOOST_FOREACH(TempOpening& opening,openings) {
|
||||||
|
|
||||||
// extrusionDir may be 0,0,0 on case where the opening mesh is not an
|
// extrusionDir may be 0,0,0 on case where the opening mesh is not an
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
7455
code/IFCReaderGen.h
7455
code/IFCReaderGen.h
File diff suppressed because it is too large
Load Diff
|
@ -208,6 +208,8 @@ struct ConversionData
|
||||||
// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,6 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
# include "IFCLoader.h"
|
# include "IFCLoader.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_M3_IMPORTER
|
|
||||||
# include "M3Importer.h"
|
|
||||||
#endif
|
|
||||||
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
|
||||||
# include "XGLLoader.h"
|
# include "XGLLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -288,9 +285,6 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
|
||||||
out.push_back( new IFCImporter() );
|
out.push_back( new IFCImporter() );
|
||||||
#endif
|
#endif
|
||||||
#if ( !defined ASSIMP_BUILD_NO_M3_IMPORTER )
|
|
||||||
out.push_back( new M3::M3Importer() );
|
|
||||||
#endif
|
|
||||||
#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER )
|
||||||
out.push_back( new XGLImporter() );
|
out.push_back( new XGLImporter() );
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -448,8 +448,8 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
|
||||||
|
|
||||||
if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {
|
if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {
|
||||||
|
|
||||||
// we have a keyframe for all of them defined .. great,
|
// we have a keyframe for all of them defined .. this means
|
||||||
// we don't need to fucking interpolate here ...
|
// we don't need to interpolate here.
|
||||||
fill.mTime = (*cur_x).time;
|
fill.mTime = (*cur_x).time;
|
||||||
|
|
||||||
fill.mValue.x = (*cur_x).value;
|
fill.mValue.x = (*cur_x).value;
|
||||||
|
|
|
@ -467,6 +467,10 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
||||||
for (; begin != end; ++begin) {
|
for (; begin != end; ++begin) {
|
||||||
aiFace& face = *begin;
|
aiFace& face = *begin;
|
||||||
|
|
||||||
|
if(face.mNumIndices < 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// LWO doc: "the normal is defined as the cross product of the first and last edges"
|
// LWO doc: "the normal is defined as the cross product of the first and last edges"
|
||||||
aiVector3D* pV1 = mesh->mVertices + face.mIndices[0];
|
aiVector3D* pV1 = mesh->mVertices + face.mIndices[0];
|
||||||
aiVector3D* pV2 = mesh->mVertices + face.mIndices[1];
|
aiVector3D* pV2 = mesh->mVertices + face.mIndices[1];
|
||||||
|
|
|
@ -464,7 +464,7 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
|
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
|
||||||
{
|
{
|
||||||
tmp = in[0] + ":\\" + in.substr(2);
|
tmp = in[0] + (":\\" + in.substr(2));
|
||||||
}
|
}
|
||||||
else tmp = in;
|
else tmp = in;
|
||||||
|
|
||||||
|
@ -480,11 +480,12 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
|
||||||
// <folder>\Scenes\<hh>\<*>.lws
|
// <folder>\Scenes\<hh>\<*>.lws
|
||||||
// where <hh> is optional.
|
// where <hh> is optional.
|
||||||
|
|
||||||
std::string test = ".." + io->getOsSeparator() + tmp;
|
std::string test = ".." + (io->getOsSeparator() + tmp);
|
||||||
if (io->Exists(test))
|
if (io->Exists(test)) {
|
||||||
return test;
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
test = ".." + io->getOsSeparator() + test;
|
test = ".." + (io->getOsSeparator() + test);
|
||||||
if (io->Exists(test)) {
|
if (io->Exists(test)) {
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
|
// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
|
||||||
#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void LogWarn (const char* message) {
|
static void LogWarn (const char* message) {
|
||||||
|
|
|
@ -1,370 +0,0 @@
|
||||||
/*
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
|
||||||
with or without modification, are permitted provided that the
|
|
||||||
following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the assimp team, nor the names of its
|
|
||||||
contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior
|
|
||||||
written permission of the assimp team.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_M3_IMPORTER
|
|
||||||
|
|
||||||
#include "M3Importer.h"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
namespace M3 {
|
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
|
||||||
"StarCraft M3 Importer",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
aiImporterFlags_SupportBinaryFlavour,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"m3"
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor.
|
|
||||||
M3Importer::M3Importer() :
|
|
||||||
m_pHead( NULL ),
|
|
||||||
m_pRefs( NULL ),
|
|
||||||
m_Buffer()
|
|
||||||
{
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor.
|
|
||||||
M3Importer::~M3Importer()
|
|
||||||
{
|
|
||||||
m_pHead = NULL;
|
|
||||||
m_pRefs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Check for readable file format.
|
|
||||||
bool M3Importer::CanRead( const std::string &rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
|
|
||||||
{
|
|
||||||
if ( !checkSig ) {
|
|
||||||
return SimpleExtensionCheck( rFile, "m3" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
const aiImporterDesc* M3Importer::GetInfo () const
|
|
||||||
{
|
|
||||||
return &desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
|
|
||||||
{
|
|
||||||
ai_assert( !pFile.empty() );
|
|
||||||
|
|
||||||
const std::string mode = "rb";
|
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode ) );
|
|
||||||
if ( NULL == file.get() ) {
|
|
||||||
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the file-size and validate it, throwing an exception when it fails
|
|
||||||
const size_t filesize = file->FileSize();
|
|
||||||
if( filesize < 1 ) {
|
|
||||||
throw DeadlyImportError( "M3-file is too small.");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Buffer.resize( filesize );
|
|
||||||
file->Read( &m_Buffer[ 0 ], sizeof( unsigned char ), filesize );
|
|
||||||
|
|
||||||
m_pHead = reinterpret_cast<MD33*>( &m_Buffer[ 0 ] );
|
|
||||||
m_pRefs = reinterpret_cast<ReferenceEntry*>( &m_Buffer[ 0 ] + m_pHead->ofsRefs );
|
|
||||||
|
|
||||||
MODL20* pMODL20( NULL );
|
|
||||||
MODL23* pMODL23( NULL );
|
|
||||||
|
|
||||||
VertexExt* pVerts1( NULL );
|
|
||||||
Vertex* pVerts2( NULL );
|
|
||||||
|
|
||||||
DIV *pViews( NULL );
|
|
||||||
Region* regions( NULL );
|
|
||||||
uint16* faces( NULL );
|
|
||||||
|
|
||||||
uint32 nVertices = 0;
|
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
switch( m_pRefs[ m_pHead->MODL.ref ].type ) {
|
|
||||||
case 20:
|
|
||||||
pMODL20 = GetEntries<MODL20>( m_pHead->MODL );
|
|
||||||
if ( ( pMODL20->flags & 0x20000) != 0 ) { // Has vertices
|
|
||||||
if( (pMODL20->flags & 0x40000) != 0 ) { // Has extra 4 byte
|
|
||||||
pVerts1 = GetEntries<VertexExt>( pMODL20->vertexData );
|
|
||||||
nVertices = pMODL20->vertexData.nEntries/sizeof(VertexExt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pVerts2 = GetEntries<Vertex>( pMODL20->vertexData );
|
|
||||||
nVertices = pMODL20->vertexData.nEntries / sizeof( Vertex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pViews = GetEntries<DIV>( pMODL20->views );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 23:
|
|
||||||
pMODL23 = GetEntries<MODL23>(m_pHead->MODL );
|
|
||||||
if( (pMODL23->flags & 0x20000) != 0 ) { // Has vertices
|
|
||||||
if( (pMODL23->flags & 0x40000) != 0 ) { // Has extra 4 byte
|
|
||||||
pVerts1 = GetEntries<VertexExt>( pMODL23->vertexData );
|
|
||||||
nVertices = pMODL23->vertexData.nEntries/sizeof( VertexExt );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pVerts2 = GetEntries<Vertex>( pMODL23->vertexData );
|
|
||||||
nVertices = pMODL23->vertexData.nEntries/sizeof( Vertex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pViews = GetEntries<DIV>( pMODL23->views );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything ok, if not throw an exception
|
|
||||||
if ( !ok ) {
|
|
||||||
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all region data
|
|
||||||
regions = GetEntries<Region>( pViews->regions );
|
|
||||||
|
|
||||||
// Get the face data
|
|
||||||
faces = GetEntries<uint16>( pViews->faces );
|
|
||||||
|
|
||||||
// Convert the vertices
|
|
||||||
std::vector<aiVector3D> vertices;
|
|
||||||
vertices.resize( nVertices );
|
|
||||||
unsigned int offset = 0;
|
|
||||||
for ( unsigned int i = 0; i < nVertices; i++ ) {
|
|
||||||
if ( pVerts1 ) {
|
|
||||||
vertices[ offset ].Set( pVerts1[ i ].pos.x, pVerts1[ i ].pos.y, pVerts1[ i ].pos.z );
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pVerts2 ) {
|
|
||||||
vertices[ offset ].Set( pVerts2[ i ].pos.x, pVerts2[ i ].pos.y, pVerts2[ i ].pos.z );
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the UV coordinates
|
|
||||||
offset = 0;
|
|
||||||
std::vector<aiVector3D> uvCoords;
|
|
||||||
uvCoords.resize( nVertices );
|
|
||||||
for( unsigned int i = 0; i < nVertices; ++i ) {
|
|
||||||
if( pVerts1 ) {
|
|
||||||
float u = (float) pVerts1[ i ].uv[ 0 ] / 2048;
|
|
||||||
float v = (float) pVerts1[ i ].uv[ 1 ] / 2048;
|
|
||||||
uvCoords[ offset ].Set( u, v, 0.0f );
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pVerts2 ) {
|
|
||||||
float u = (float) pVerts2[ i ].uv[ 0 ] / 2048;
|
|
||||||
float v = (float) pVerts2[ i ].uv[ 1 ] / 2048;
|
|
||||||
uvCoords[ offset ].Set( u, v, 0.0f );
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the normals
|
|
||||||
std::vector<aiVector3D> normals;
|
|
||||||
normals.resize( nVertices );
|
|
||||||
float w = 0.0f;
|
|
||||||
Vec3D norm;
|
|
||||||
offset = 0;
|
|
||||||
for( unsigned int i = 0; i < nVertices; i++ ) {
|
|
||||||
w = 0.0f;
|
|
||||||
if( pVerts1 ) {
|
|
||||||
norm.x = (float) 2*pVerts1[ i ].normal[ 0 ]/255.0f - 1;
|
|
||||||
norm.y = (float) 2*pVerts1[ i ].normal[ 1 ]/255.0f - 1;
|
|
||||||
norm.z = (float) 2*pVerts1[ i ].normal[ 2 ]/255.0f - 1;
|
|
||||||
w = (float) pVerts1[ i ].normal[ 3 ]/255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pVerts2 ) {
|
|
||||||
norm.x = (float) 2*pVerts2[ i ].normal[ 0 ]/255.0f - 1;
|
|
||||||
norm.y = (float) 2*pVerts2[ i ].normal[ 1 ]/255.0f - 1;
|
|
||||||
norm.z = (float) 2*pVerts2[ i ].normal[ 2 ]/255.0f - 1;
|
|
||||||
w = (float) pVerts2[ i ].normal[ 3 ] / 255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( w ) {
|
|
||||||
const float invW = 1.0f / w;
|
|
||||||
norm.x = norm.x * invW;
|
|
||||||
norm.y = norm.y * invW;
|
|
||||||
norm.z = norm.z * invW;
|
|
||||||
normals[ offset ].Set( norm.x, norm.y, norm.z );
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the data into the assimp specific data structures
|
|
||||||
convertToAssimp( pFile, pScene, pViews, regions, faces, vertices, uvCoords, normals );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews,
|
|
||||||
Region *pRegions, uint16 *pFaces,
|
|
||||||
const std::vector<aiVector3D> &vertices,
|
|
||||||
const std::vector<aiVector3D> &uvCoords,
|
|
||||||
const std::vector<aiVector3D> &normals )
|
|
||||||
{
|
|
||||||
std::vector<aiMesh*> MeshArray;
|
|
||||||
|
|
||||||
// Create the root node
|
|
||||||
pScene->mRootNode = createNode( NULL );
|
|
||||||
|
|
||||||
// Set the name of the scene
|
|
||||||
pScene->mRootNode->mName.Set( pFile );
|
|
||||||
|
|
||||||
aiNode *pRootNode = pScene->mRootNode;
|
|
||||||
aiNode *pCurrentNode = NULL;
|
|
||||||
|
|
||||||
// Lets create the nodes
|
|
||||||
pRootNode->mNumChildren = pViews->regions.nEntries;
|
|
||||||
if ( pRootNode->mNumChildren > 0 ) {
|
|
||||||
pRootNode->mChildren = new aiNode*[ pRootNode->mNumChildren ];
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( unsigned int i=0; i<pRootNode->mNumChildren; ++i ) {
|
|
||||||
//pRegions[ i ].
|
|
||||||
// Create a new node
|
|
||||||
pCurrentNode = createNode( pRootNode );
|
|
||||||
std::stringstream stream;
|
|
||||||
stream << "Node_" << i;
|
|
||||||
pCurrentNode->mName.Set( stream.str().c_str() );
|
|
||||||
pRootNode->mChildren[ i ] = pCurrentNode;
|
|
||||||
|
|
||||||
// Loop over the faces of the nodes
|
|
||||||
unsigned int numFaces = ( ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ) - pRegions[ i ].ofsIndices ) / 3;
|
|
||||||
aiMesh *pMesh = new aiMesh;
|
|
||||||
MeshArray.push_back( pMesh );
|
|
||||||
pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
|
||||||
|
|
||||||
pMesh->mNumFaces = numFaces;
|
|
||||||
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
|
|
||||||
aiFace *pCurrentFace = NULL;
|
|
||||||
unsigned int faceIdx = 0;
|
|
||||||
for ( unsigned int j = pRegions[ i ].ofsIndices; j < ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ); j += 3 ) {
|
|
||||||
pCurrentFace = &( pMesh->mFaces[ faceIdx ] );
|
|
||||||
faceIdx++;
|
|
||||||
pCurrentFace->mNumIndices = 3;
|
|
||||||
pCurrentFace->mIndices = new unsigned int[ 3 ];
|
|
||||||
pCurrentFace->mIndices[ 0 ] = pFaces[ j ];
|
|
||||||
pCurrentFace->mIndices[ 1 ] = pFaces[ j+1 ];
|
|
||||||
pCurrentFace->mIndices[ 2 ] = pFaces[ j+2 ];
|
|
||||||
}
|
|
||||||
// Now we can create the vertex data itself
|
|
||||||
pCurrentNode->mNumMeshes = 1;
|
|
||||||
pCurrentNode->mMeshes = new unsigned int[ 1 ];
|
|
||||||
const unsigned int meshIdx = MeshArray.size() - 1;
|
|
||||||
pCurrentNode->mMeshes[ 0 ] = meshIdx;
|
|
||||||
createVertexData( pMesh, vertices, uvCoords, normals );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the meshes into the scene
|
|
||||||
pScene->mNumMeshes = MeshArray.size();
|
|
||||||
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
|
|
||||||
unsigned int pos = 0;
|
|
||||||
for ( std::vector<aiMesh*>::iterator it = MeshArray.begin(); it != MeshArray.end(); ++it ) {
|
|
||||||
pScene->mMeshes[ pos ] = *it;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
void M3Importer::createVertexData( aiMesh *pMesh, const std::vector<aiVector3D> &vertices,
|
|
||||||
const std::vector<aiVector3D> &uvCoords,
|
|
||||||
const std::vector<aiVector3D> &normals )
|
|
||||||
{
|
|
||||||
pMesh->mNumVertices = pMesh->mNumFaces * 3;
|
|
||||||
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
|
||||||
pMesh->mNumUVComponents[ 0 ] = 2;
|
|
||||||
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
|
|
||||||
pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
|
|
||||||
unsigned int pos = 0;
|
|
||||||
for ( unsigned int currentFace = 0; currentFace < pMesh->mNumFaces; currentFace++ ) {
|
|
||||||
aiFace *pFace = &( pMesh->mFaces[ currentFace ] );
|
|
||||||
for ( unsigned int currentIdx=0; currentIdx<pFace->mNumIndices; currentIdx++ ) {
|
|
||||||
const unsigned int idx = pFace->mIndices[ currentIdx ];
|
|
||||||
if ( vertices.size() > idx ) {
|
|
||||||
pMesh->mVertices[ pos ] = vertices[ idx ];
|
|
||||||
pMesh->mNormals[ pos ] = normals[ idx ];
|
|
||||||
pMesh->mTextureCoords[ 0 ]->x = uvCoords[ idx ].x;
|
|
||||||
pMesh->mTextureCoords[ 0 ]->y = uvCoords[ idx ].y;
|
|
||||||
pFace->mIndices[ currentIdx ] = pos;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
aiNode *M3Importer::createNode( aiNode *pParent )
|
|
||||||
{
|
|
||||||
aiNode *pNode = new aiNode;
|
|
||||||
if ( pParent )
|
|
||||||
pNode->mParent = pParent;
|
|
||||||
else
|
|
||||||
pNode->mParent = NULL;
|
|
||||||
|
|
||||||
return pNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
} // Namespace M3
|
|
||||||
} // Namespace Assimp
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_M3_IMPORTER
|
|
|
@ -1,726 +0,0 @@
|
||||||
/*
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
|
||||||
with or without modification, are permitted provided that the
|
|
||||||
following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the assimp team, nor the names of its
|
|
||||||
contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior
|
|
||||||
written permission of the assimp team.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#ifndef AI_M3LOADER_H_INCLUDED
|
|
||||||
#define AI_M3LOADER_H_INCLUDED
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
|
|
||||||
namespace M3 {
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// The following data definitions are from http://code.google.com/p/libm3/, many thanks for that
|
|
||||||
// help.
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
typedef unsigned char uint8;
|
|
||||||
typedef char int8;
|
|
||||||
typedef unsigned short uint16;
|
|
||||||
typedef short int16;
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
typedef int int32;
|
|
||||||
|
|
||||||
class Vec3D
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
float x,y,z;
|
|
||||||
|
|
||||||
Vec3D(float x0 = 0.0f, float y0 = 0.0f, float z0 = 0.0f) : x(x0), y(y0), z(z0) {}
|
|
||||||
|
|
||||||
Vec3D(const Vec3D& v) : x(v.x), y(v.y), z(v.z) {}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
x = y = z = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D& operator= (const Vec3D &v)
|
|
||||||
{
|
|
||||||
x = v.x;
|
|
||||||
y = v.y;
|
|
||||||
z = v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D operator+ (const Vec3D &v) const
|
|
||||||
{
|
|
||||||
Vec3D r(x+v.x,y+v.y,z+v.z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D operator- (const Vec3D &v) const
|
|
||||||
{
|
|
||||||
Vec3D r(x-v.x,y-v.y,z-v.z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float operator* (const Vec3D &v) const
|
|
||||||
{
|
|
||||||
return x*v.x + y*v.y + z*v.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D operator* (float d) const
|
|
||||||
{
|
|
||||||
Vec3D r(x*d,y*d,z*d);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D operator/ (float d) const
|
|
||||||
{
|
|
||||||
Vec3D r(x/d,y/d,z/d);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend Vec3D operator* (float d, const Vec3D& v)
|
|
||||||
{
|
|
||||||
return v * d;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cross Product
|
|
||||||
Vec3D operator% (const Vec3D &v) const
|
|
||||||
{
|
|
||||||
Vec3D r(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D& operator+= (const Vec3D &v)
|
|
||||||
{
|
|
||||||
x += v.x;
|
|
||||||
y += v.y;
|
|
||||||
z += v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D& operator-= (const Vec3D &v)
|
|
||||||
{
|
|
||||||
x -= v.x;
|
|
||||||
y -= v.y;
|
|
||||||
z -= v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D& operator*= (float d)
|
|
||||||
{
|
|
||||||
x *= d;
|
|
||||||
y *= d;
|
|
||||||
z *= d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
float lengthSquared() const
|
|
||||||
{
|
|
||||||
return x*x+y*y+z*z;
|
|
||||||
}
|
|
||||||
|
|
||||||
float length() const
|
|
||||||
{
|
|
||||||
return sqrtf(x*x+y*y+z*z);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D& normalize()
|
|
||||||
{
|
|
||||||
this->operator*= (1.0f/length());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3D operator~ () const
|
|
||||||
{
|
|
||||||
Vec3D r(*this);
|
|
||||||
r.normalize();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator float*()
|
|
||||||
{
|
|
||||||
return (float*)this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Vec2D
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
float x,y;
|
|
||||||
|
|
||||||
Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {}
|
|
||||||
|
|
||||||
Vec2D(const Vec2D& v) : x(v.x), y(v.y) {}
|
|
||||||
|
|
||||||
Vec2D& operator= (const Vec2D &v)
|
|
||||||
{
|
|
||||||
x = v.x;
|
|
||||||
y = v.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D operator+ (const Vec2D &v) const
|
|
||||||
{
|
|
||||||
Vec2D r(x+v.x,y+v.y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D operator- (const Vec2D &v) const
|
|
||||||
{
|
|
||||||
Vec2D r(x-v.x,y-v.y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float operator* (const Vec2D &v) const
|
|
||||||
{
|
|
||||||
return x*v.x + y*v.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D operator* (float d) const
|
|
||||||
{
|
|
||||||
Vec2D r(x*d,y*d);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend Vec2D operator* (float d, const Vec2D& v)
|
|
||||||
{
|
|
||||||
return v * d;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D& operator+= (const Vec2D &v)
|
|
||||||
{
|
|
||||||
x += v.x;
|
|
||||||
y += v.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D& operator-= (const Vec2D &v)
|
|
||||||
{
|
|
||||||
x -= v.x;
|
|
||||||
y -= v.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D& operator*= (float d)
|
|
||||||
{
|
|
||||||
x *= d;
|
|
||||||
y *= d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
float lengthSquared() const
|
|
||||||
{
|
|
||||||
return x*x+y*y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float length() const
|
|
||||||
{
|
|
||||||
return sqrtf(x*x+y*y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D& normalize()
|
|
||||||
{
|
|
||||||
this->operator*= (1.0f/length());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2D operator~ () const
|
|
||||||
{
|
|
||||||
Vec2D r(*this);
|
|
||||||
r.normalize();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator float*()
|
|
||||||
{
|
|
||||||
return (float*)this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline
|
|
||||||
void rotate(float x0, float y0, float *x, float *y, float angle)
|
|
||||||
{
|
|
||||||
float xa = *x - x0, ya = *y - y0;
|
|
||||||
*x = xa*cosf(angle) - ya*sinf(angle) + x0;
|
|
||||||
*y = xa*sinf(angle) + ya*cosf(angle) + y0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Reference
|
|
||||||
{
|
|
||||||
uint32 nEntries; // Code 0x00
|
|
||||||
uint32 ref; // Code 0x04
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ReferenceEntry
|
|
||||||
{
|
|
||||||
char id[ 4 ]; // Code 0x00
|
|
||||||
uint32 offset; // Code 0x04
|
|
||||||
uint32 nEntries; // Code 0x08
|
|
||||||
uint32 type; // Code 0x0C
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MD33
|
|
||||||
{
|
|
||||||
char id[4]; // Code 0x00
|
|
||||||
uint32 ofsRefs; // Code 0x04
|
|
||||||
uint32 nRefs; // Code 0x08
|
|
||||||
Reference MODL; // Code 0x0C
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ModelType
|
|
||||||
{
|
|
||||||
Type1 = 20,
|
|
||||||
Type2 = 23
|
|
||||||
};
|
|
||||||
|
|
||||||
enum VertexFormat
|
|
||||||
{
|
|
||||||
Vertex_Standard,
|
|
||||||
Vertex_Extended
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MODL23
|
|
||||||
{
|
|
||||||
Reference name; // Code 0x00
|
|
||||||
uint32 version; // Code 0x08
|
|
||||||
Reference sequenceHeader; // Code 0x0C
|
|
||||||
Reference sequenceData; // Code 0x14
|
|
||||||
Reference sequenceLookup; // Code 0x1C
|
|
||||||
uint32 d2; // Code 0x24
|
|
||||||
uint32 d3; // Code 0x28
|
|
||||||
uint32 d4; // Code 0x2C
|
|
||||||
Reference STS; // Code 0x30
|
|
||||||
Reference bones; // Code 0x38
|
|
||||||
uint32 d5; // Code 0x40
|
|
||||||
uint32 flags; // Code 0x44
|
|
||||||
Reference vertexData; // Code 0x48
|
|
||||||
Reference views; // Code 0x50
|
|
||||||
Reference B; // Code 0x58
|
|
||||||
|
|
||||||
Vec3D extents[2]; // Code 0x60
|
|
||||||
float radius; // Code 0x78
|
|
||||||
|
|
||||||
uint32 d7; // Code 0x7C
|
|
||||||
uint32 d8; // Code 0x80
|
|
||||||
uint32 d9; // Code 0x84
|
|
||||||
uint32 d10; // Code 0x88
|
|
||||||
uint32 d11; // Code 0x8C
|
|
||||||
uint32 d12; // Code 0x90
|
|
||||||
uint32 d13; // Code 0x94
|
|
||||||
uint32 d14; // Code 0x98
|
|
||||||
uint32 d15; // Code 0x9C
|
|
||||||
uint32 d16; // Code 0xA0
|
|
||||||
uint32 d17; // Code 0xA4
|
|
||||||
uint32 d18; // Code 0xA8
|
|
||||||
uint32 d19; // Code 0xAC
|
|
||||||
|
|
||||||
Reference attachments; // Code 0xB0
|
|
||||||
Reference attachmentLookup; // Code 0xB8
|
|
||||||
Reference lights; // Code 0xC0
|
|
||||||
Reference SHBX; // Code 0xC8
|
|
||||||
Reference cameras; // Code 0xD0
|
|
||||||
Reference D; // Code 0xD8
|
|
||||||
Reference materialLookup; // Code 0xE0
|
|
||||||
Reference materials; // Code 0xE8
|
|
||||||
Reference DIS; // Code 0xF0
|
|
||||||
Reference CMP; // Code 0xF8
|
|
||||||
|
|
||||||
Reference TER; // Code 0x10
|
|
||||||
Reference VOL; // Code 0x10
|
|
||||||
uint32 d21; // Code 0x11
|
|
||||||
uint32 d22; // Code 0x11
|
|
||||||
Reference CREP; // Code 0x11
|
|
||||||
Reference PAR; // Code 0x12
|
|
||||||
Reference PARC; // Code 0x12
|
|
||||||
Reference RIB; // Code 0x13
|
|
||||||
Reference PROJ; // Code 0x13
|
|
||||||
Reference FOR; // Code 0x14
|
|
||||||
Reference WRP; // Code 0x14
|
|
||||||
uint32 d24; // Code 0x15
|
|
||||||
uint32 d25; // Code 0x15
|
|
||||||
Reference PHRB; // Code 0x15
|
|
||||||
uint32 d27; // Code 0x16
|
|
||||||
uint32 d28; // Code 0x16
|
|
||||||
uint32 d29; // Code 0x16
|
|
||||||
uint32 d30; // Code 0x16
|
|
||||||
uint32 d32; // Code 0x17
|
|
||||||
uint32 d33; // Code 0x17
|
|
||||||
Reference IKJT; // Code 0x17
|
|
||||||
uint32 d35; // Code 0x18
|
|
||||||
uint32 d36; // Code 0x18
|
|
||||||
Reference PATU; // Code 0x18
|
|
||||||
Reference TRGD; // Code 0x19
|
|
||||||
Reference IREF; // Code 0x19
|
|
||||||
Reference E; // Code 0x1A
|
|
||||||
float matrix[4][4]; // Code 0x1A
|
|
||||||
Vec3D extent[2]; // Code 0x1E
|
|
||||||
float rad; // Code 0x20
|
|
||||||
Reference SSGS; // Code 0x20
|
|
||||||
Reference ATVL; // Code 0x20
|
|
||||||
uint32 d61; // Code 0x21
|
|
||||||
Reference F; // uint16, Code6 0x21
|
|
||||||
Reference G; // uint16, Code 0x21
|
|
||||||
Reference BBSC; // Code 0x22
|
|
||||||
Reference TMD; // Code 0x22
|
|
||||||
uint32 d62; // Code 0x23
|
|
||||||
uint32 d63; // Code 0x23
|
|
||||||
uint32 d64; // Code 0x23
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MODL20
|
|
||||||
{
|
|
||||||
Reference name; // Code 0x00
|
|
||||||
uint32 version; // Code 0x08
|
|
||||||
Reference sequenceHeader; // Code 0x0C
|
|
||||||
Reference sequenceData; // Code 0x14
|
|
||||||
Reference sequenceLookup; // Code 0x1C
|
|
||||||
uint32 d2; // Code 0x24
|
|
||||||
uint32 d3; // Code 0x28
|
|
||||||
uint32 d4; // Code 0x2C
|
|
||||||
Reference STS; // Code 0x30
|
|
||||||
Reference bones; // Code 0x38
|
|
||||||
uint32 d5; // Code 0x44
|
|
||||||
uint32 flags; // Code 0x44
|
|
||||||
Reference vertexData; // uint8, Code 0x48
|
|
||||||
Reference views; // Code 0x50
|
|
||||||
Reference B; // uint16, Code 0x58
|
|
||||||
|
|
||||||
Vec3D extents[2]; // Code 0x60
|
|
||||||
float radius; // Code 0x78
|
|
||||||
|
|
||||||
uint32 d7; // Code 0x7C
|
|
||||||
uint32 d8; // Code 0x80
|
|
||||||
uint32 d9; // Code 0x84
|
|
||||||
uint32 d10; // Code 0x88
|
|
||||||
uint32 d11; // Code 0x8C
|
|
||||||
uint32 d12; // Code 0x90
|
|
||||||
uint32 d13; // Code 0x94
|
|
||||||
uint32 d14; // Code 0x98
|
|
||||||
uint32 d15; // Code 0x9C
|
|
||||||
uint32 d16; // Code 0xA0
|
|
||||||
uint32 d17; // Code 0xA4
|
|
||||||
uint32 d18; // Code 0xA8
|
|
||||||
uint32 d19; // Code 0xAC
|
|
||||||
|
|
||||||
Reference attachments; // Code 0xB0
|
|
||||||
Reference attachmentLookup; // uint16, Code 0xB8
|
|
||||||
Reference lights; // Code 0xC0
|
|
||||||
Reference cameras; // Code 0xC8
|
|
||||||
Reference D; // uint16, Code 0xD0
|
|
||||||
Reference materialLookup; // Code 0xD8
|
|
||||||
Reference materials; // Code 0xE0
|
|
||||||
Reference DIS; // Code 0xE8
|
|
||||||
Reference CMP; // Code 0xF0
|
|
||||||
Reference TER; // Code 0xF8
|
|
||||||
|
|
||||||
uint32 d20; // Code 0x10
|
|
||||||
uint32 d21; // Code 0x10
|
|
||||||
uint32 d22; // Code 0x10
|
|
||||||
uint32 d23; // Code 0x10
|
|
||||||
Reference CREP; // Code 0x11
|
|
||||||
Reference PAR; // Code 0x11
|
|
||||||
Reference PARC; // Code 0x12
|
|
||||||
Reference RIB; // Code 0x12
|
|
||||||
Reference PROJ; // Code 0x13
|
|
||||||
Reference FOR; // Code 0x13
|
|
||||||
uint32 d25; // Code 0x14
|
|
||||||
uint32 d26; // Code 0x14
|
|
||||||
uint32 d27; // Code 0x14
|
|
||||||
uint32 d28; // Code 0x14
|
|
||||||
Reference PHRB; // Code 0x15
|
|
||||||
uint32 d30; // Code 0x15
|
|
||||||
uint32 d31; // Code 0x15
|
|
||||||
uint32 d32; // Code 0x16
|
|
||||||
uint32 d33; // Code 0x16
|
|
||||||
uint32 d34; // Code 0x16
|
|
||||||
uint32 d35; // Code 0x16
|
|
||||||
Reference IKJT; // Code 0x17
|
|
||||||
uint32 d36; // Code 0x17
|
|
||||||
uint32 d37; // Code 0x17
|
|
||||||
Reference PATU; // Code 0x18
|
|
||||||
Reference TRGD; // Code 0x18
|
|
||||||
Reference IREF; // Code 0x19
|
|
||||||
Reference E; // int32, Code 0x19
|
|
||||||
|
|
||||||
float matrix[4][4]; // Code 0x1A
|
|
||||||
Vec3D extent[2]; // Code 0x1E
|
|
||||||
float rad; // Code 0x1F
|
|
||||||
|
|
||||||
Reference SSGS; // Code 0x1F
|
|
||||||
uint32 d38; // Code 0x20
|
|
||||||
uint32 d39; // Code 0x20
|
|
||||||
Reference BBSC; // Code 0x20
|
|
||||||
|
|
||||||
uint32 d40; // Code 0x21
|
|
||||||
uint32 d41; // Code 0x21
|
|
||||||
uint32 d42; // Code 0x21
|
|
||||||
uint32 d43; // Code 0x22
|
|
||||||
uint32 d44; // Code 0x22
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BONE
|
|
||||||
{
|
|
||||||
int32 d1; // Keybone?
|
|
||||||
Reference name;
|
|
||||||
uint32 flags;
|
|
||||||
int16 parent;
|
|
||||||
int16 s1;
|
|
||||||
|
|
||||||
float floats[ 34 ];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VertexExt // 36 byte
|
|
||||||
{
|
|
||||||
Vec3D pos;
|
|
||||||
uint8 boneWeight[ 4 ];
|
|
||||||
uint8 boneIndex[ 4 ];
|
|
||||||
uint8 normal[ 4 ]; //normal_x = (float)normal[0]/255.0f...
|
|
||||||
int16 uv[ 2 ];
|
|
||||||
uint32 d1;
|
|
||||||
uint8 tangent[ 4 ];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vertex // 32 byte
|
|
||||||
{
|
|
||||||
Vec3D pos;
|
|
||||||
uint8 boneWeight[4];
|
|
||||||
uint8 boneIndex[4];
|
|
||||||
uint8 normal[4]; //normal_x = (float)normal[0]/255.0f...
|
|
||||||
int16 uv[2];
|
|
||||||
uint8 tangent[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MATM
|
|
||||||
{
|
|
||||||
uint32 d1;
|
|
||||||
uint32 d2; // Index into MAT-table?
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MAT
|
|
||||||
{
|
|
||||||
Reference name;
|
|
||||||
int ukn1[ 8 ];
|
|
||||||
float x, y; //always 1.0f
|
|
||||||
Reference layers[13];
|
|
||||||
int ukn2[15];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LAYR
|
|
||||||
{
|
|
||||||
int unk;
|
|
||||||
Reference name;
|
|
||||||
float unk2[85];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DIV
|
|
||||||
{
|
|
||||||
Reference faces; // Code 0x00
|
|
||||||
Reference regions; // Code 0x08
|
|
||||||
Reference BAT; // Code 0x10
|
|
||||||
Reference MSEC; // Code 0x18
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Region
|
|
||||||
{
|
|
||||||
uint32 unk;
|
|
||||||
uint16 ofsVertices;
|
|
||||||
uint16 nVertices;
|
|
||||||
uint32 ofsIndices;
|
|
||||||
uint32 nIndices; // reference into DIV.faces
|
|
||||||
uint8 unknown[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CAM
|
|
||||||
{
|
|
||||||
int32 d1; // Code 0x00
|
|
||||||
Reference name; // Code 0x04
|
|
||||||
uint16 flags1; // Code 0x0C
|
|
||||||
uint16 flags2; // Code 0x0E
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EVNT
|
|
||||||
{
|
|
||||||
Reference name; // Code 0x00
|
|
||||||
int16 unk1[4]; // Code 0x08
|
|
||||||
float matrix[4][4]; // Code 0x10
|
|
||||||
int32 unk2[4]; // Code 0x50
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ATT
|
|
||||||
{
|
|
||||||
int32 unk; // Code 0x00
|
|
||||||
Reference name; // Code 0x04
|
|
||||||
int32 bone; // Code 0x0C
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PHSH
|
|
||||||
{
|
|
||||||
float m[ 4 ][ 4 ];
|
|
||||||
float f1;
|
|
||||||
float f2;
|
|
||||||
Reference refs[ 5 ];
|
|
||||||
float f3;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SEQS
|
|
||||||
{
|
|
||||||
int32 d1; // Code 0x00
|
|
||||||
int32 d2; // Code 0x04
|
|
||||||
Reference name; // Code 0x08
|
|
||||||
int32 d3; // Code 0x10
|
|
||||||
uint32 length; // Code 0x14
|
|
||||||
int32 d4; // Code 0x18
|
|
||||||
uint32 flags; // Code 0x1C
|
|
||||||
int32 unk[5]; // Code 0x20
|
|
||||||
Vec3D extents[2]; // Code 0x34
|
|
||||||
float radius; // Code 0x4C
|
|
||||||
int32 d5; // Code 0x50
|
|
||||||
int32 d6; // Code 0x54
|
|
||||||
};
|
|
||||||
|
|
||||||
struct STC
|
|
||||||
{
|
|
||||||
Reference name; // Code 0x00
|
|
||||||
uint16 s1; // Code 0x08
|
|
||||||
uint16 s2; // Code 0x0A
|
|
||||||
uint16 s3; // Code 0x0C
|
|
||||||
uint16 s4; // Code 0x0E
|
|
||||||
Reference unk2; // uint32 // Code 0x12
|
|
||||||
Reference unk3; // uint32 // Code 0x1A
|
|
||||||
uint32 d3; // Code 0x22
|
|
||||||
Reference evt; // Code 0x24
|
|
||||||
Reference unk4[11]; // Seems to be transformation data // Code 0x2C
|
|
||||||
Reference bnds; // Code 0x84
|
|
||||||
};
|
|
||||||
|
|
||||||
struct STS
|
|
||||||
{
|
|
||||||
Reference unk1; // uint32 // Code 0x00
|
|
||||||
int32 unk[3]; // Code 0x08
|
|
||||||
int16 s1; // Code 0x14
|
|
||||||
int16 s2; // Code 0x16
|
|
||||||
};
|
|
||||||
|
|
||||||
struct STG
|
|
||||||
{
|
|
||||||
Reference name; // Code 0x00
|
|
||||||
Reference stcID; // Code 0x08
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SD
|
|
||||||
{
|
|
||||||
Reference timeline; // Code 0x00
|
|
||||||
uint32 flags; // Code 0x08
|
|
||||||
uint32 length; // Code 0x0C
|
|
||||||
Reference data; // Code 0x10
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BNDS
|
|
||||||
{
|
|
||||||
Vec3D extents1[2]; // Code 0x00
|
|
||||||
float radius1; // Code 0x18
|
|
||||||
Vec3D extents2[2]; // Code 0x1C
|
|
||||||
float radius2; // Code 0x34
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VEC2
|
|
||||||
{
|
|
||||||
float x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VEC3
|
|
||||||
{
|
|
||||||
float x, y, z;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VEC4
|
|
||||||
{
|
|
||||||
float x, y, z, w;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QUAT
|
|
||||||
{
|
|
||||||
float x, y, z, w;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
/** Loader to import M3-models.
|
|
||||||
*/
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
class M3Importer : public BaseImporter
|
|
||||||
{
|
|
||||||
friend class Importer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// @brief The default constructor.
|
|
||||||
M3Importer();
|
|
||||||
|
|
||||||
/// @brief The destructor.
|
|
||||||
~M3Importer();
|
|
||||||
|
|
||||||
/// @brief Returns whether the class can handle the format of the given file.
|
|
||||||
/// @remark See BaseImporter::CanRead() for details.
|
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const aiImporterDesc* GetInfo () const;
|
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
|
|
||||||
void convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews, Region *pRegions, uint16 *pFaces,
|
|
||||||
const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &uvCoords, const std::vector<aiVector3D> &normals );
|
|
||||||
void createVertexData( aiMesh *pMesh, const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &uvCoords,
|
|
||||||
const std::vector<aiVector3D> &normals );
|
|
||||||
aiNode *createNode( aiNode *pParent );
|
|
||||||
template<typename T>
|
|
||||||
T* GetEntries( Reference ref );
|
|
||||||
|
|
||||||
private:
|
|
||||||
MD33 *m_pHead;
|
|
||||||
ReferenceEntry *m_pRefs;
|
|
||||||
std::vector<unsigned char> m_Buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
template<typename T>
|
|
||||||
inline
|
|
||||||
T* M3Importer::GetEntries( Reference ref )
|
|
||||||
{
|
|
||||||
return (T*) ( &m_Buffer[ 0 ] + m_pRefs[ ref.ref ].offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
} // Namespace M3
|
|
||||||
} // Namespace Assimp
|
|
||||||
|
|
||||||
#endif // AI_M3LOADER_H_INCLUDED
|
|
|
@ -187,7 +187,6 @@ void MD5Importer::LoadFileIntoMemory (IOStream* file)
|
||||||
ai_assert(fileSize);
|
ai_assert(fileSize);
|
||||||
|
|
||||||
// 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
|
||||||
pScene = pScene;
|
|
||||||
mBuffer = new char[fileSize+1];
|
mBuffer = new char[fileSize+1];
|
||||||
file->Read( (void*)mBuffer, 1, fileSize);
|
file->Read( (void*)mBuffer, 1, fileSize);
|
||||||
iLineNumber = 1;
|
iLineNumber = 1;
|
||||||
|
|
|
@ -787,7 +787,6 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// What the fuck does this function do? Can't remember
|
|
||||||
void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||||
const unsigned char* szCurrent,
|
const unsigned char* szCurrent,
|
||||||
const unsigned char** szCurrentOut,
|
const unsigned char** szCurrentOut,
|
||||||
|
|
|
@ -102,7 +102,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// data is given in floats, simply copy it
|
// data is given in floats, simply copy it
|
||||||
unsigned int iWrite;
|
unsigned int iWrite = 0;
|
||||||
if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
|
if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
|
||||||
iWrite = prop->mDataLength / sizeof(float);
|
iWrite = prop->mDataLength / sizeof(float);
|
||||||
if (pMax) {
|
if (pMax) {
|
||||||
|
@ -175,7 +175,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// data is given in ints, simply copy it
|
// data is given in ints, simply copy it
|
||||||
unsigned int iWrite;
|
unsigned int iWrite = 0;
|
||||||
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
|
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
|
||||||
iWrite = prop->mDataLength / sizeof(int32_t);
|
iWrite = prop->mDataLength / sizeof(int32_t);
|
||||||
if (pMax) {
|
if (pMax) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
#ifndef AI_BUILD_NO_NDO_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
||||||
#include "NDOLoader.h"
|
#include "NDOLoader.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -59,10 +59,16 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
// we're still here - export successfully completed. Write both the main OBJ file and the material script
|
// we're still here - export successfully completed. Write both the main OBJ file and the material script
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
||||||
|
}
|
||||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
|
||||||
|
}
|
||||||
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,6 +283,7 @@ struct Model
|
||||||
m_pCurrent(NULL),
|
m_pCurrent(NULL),
|
||||||
m_pCurrentMaterial(NULL),
|
m_pCurrentMaterial(NULL),
|
||||||
m_pDefaultMaterial(NULL),
|
m_pDefaultMaterial(NULL),
|
||||||
|
m_pGroupFaceIDs(NULL),
|
||||||
m_strActiveGroup(""),
|
m_strActiveGroup(""),
|
||||||
m_pCurrentMesh(NULL)
|
m_pCurrentMesh(NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -528,18 +528,12 @@ int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
|
||||||
// Getter for a group name.
|
// Getter for a group name.
|
||||||
void ObjFileParser::getGroupName()
|
void ObjFileParser::getGroupName()
|
||||||
{
|
{
|
||||||
// Get next word from data buffer
|
std::string strGroupName;
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
|
||||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
|
||||||
if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
|
if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Store the group name in the group library
|
|
||||||
char *pStart = &(*m_DataIt);
|
|
||||||
while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
|
|
||||||
m_DataIt++;
|
|
||||||
std::string strGroupName( pStart, &(*m_DataIt) );
|
|
||||||
|
|
||||||
// Change active group, if necessary
|
// Change active group, if necessary
|
||||||
if ( m_pModel->m_strActiveGroup != strGroupName )
|
if ( m_pModel->m_strActiveGroup != strGroupName )
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,6 +165,15 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||||
//____________________________________________________________
|
//____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
//skip submeshnames (stupid irrxml)
|
||||||
|
if(MeshFile->getNodeName()==string("submeshnames"))
|
||||||
|
{
|
||||||
|
XmlRead(MeshFile.get());
|
||||||
|
while(MeshFile->getNodeName()==string("submesh"))
|
||||||
|
XmlRead(MeshFile.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------Load the skeleton: -------------------------------
|
//----------------Load the skeleton: -------------------------------
|
||||||
vector<Bone> Bones;
|
vector<Bone> Bones;
|
||||||
vector<Animation> Animations;
|
vector<Animation> Animations;
|
||||||
|
|
|
@ -64,10 +64,7 @@ namespace Ogre
|
||||||
|
|
||||||
aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
|
aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
|
||||||
{
|
{
|
||||||
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
/*For better understanding of the material parser, here is a material example file:
|
||||||
(void)m_CurrentScene;
|
|
||||||
|
|
||||||
/*For bettetr understanding of the material parser, here is a material example file:
|
|
||||||
|
|
||||||
material Sarg
|
material Sarg
|
||||||
{
|
{
|
||||||
|
@ -143,7 +140,7 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
|
||||||
if(NULL==MatFilePtr)
|
if(NULL==MatFilePtr)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
|
DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
|
||||||
return NULL;
|
return new aiMaterial();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsi
|
||||||
XmlRead(Reader);
|
XmlRead(Reader);
|
||||||
|
|
||||||
/*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers)
|
/*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers)
|
||||||
so the break condition is a bit tricky (well, IrrXML just sucks :( )*/
|
so the break condition is a bit tricky */
|
||||||
while(Reader->getNodeName()==string("vertex")
|
while(Reader->getNodeName()==string("vertex")
|
||||||
||Reader->getNodeName()==string("position")
|
||Reader->getNodeName()==string("position")
|
||||||
||Reader->getNodeName()==string("normal")
|
||Reader->getNodeName()==string("normal")
|
||||||
|
|
|
@ -77,8 +77,6 @@ void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vecto
|
||||||
if(!SkeletonFile)
|
if(!SkeletonFile)
|
||||||
throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName);
|
throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName);
|
||||||
|
|
||||||
//Quick note: Whoever read this should know this one thing: irrXml fucking sucks!!!
|
|
||||||
|
|
||||||
XmlRead(SkeletonFile);
|
XmlRead(SkeletonFile);
|
||||||
if(string("skeleton")!=SkeletonFile->getNodeName())
|
if(string("skeleton")!=SkeletonFile->getNodeName())
|
||||||
throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName);
|
throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName);
|
||||||
|
@ -169,12 +167,12 @@ void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vecto
|
||||||
Bones[ChildId].ParentId=ParentId;
|
Bones[ChildId].ParentId=ParentId;
|
||||||
Bones[ParentId].Children.push_back(ChildId);
|
Bones[ParentId].Children.push_back(ChildId);
|
||||||
|
|
||||||
XmlRead(SkeletonFile);//I once forget this line, which led to an endless loop, did i mentioned, that irrxml sucks??
|
XmlRead(SkeletonFile);
|
||||||
}
|
}
|
||||||
//_____________________________________________________________________________
|
//_____________________________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
//--------- Calculate the WorldToBoneSpace Matrix recursivly for all bones: ------------------
|
//--------- Calculate the WorldToBoneSpace Matrix recursively for all bones: ------------------
|
||||||
BOOST_FOREACH(Bone &theBone, Bones)
|
BOOST_FOREACH(Bone &theBone, Bones)
|
||||||
{
|
{
|
||||||
if(-1==theBone.ParentId) //the bone is a root bone
|
if(-1==theBone.ParentId) //the bone is a root bone
|
||||||
|
|
|
@ -57,6 +57,10 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
|
|
||||||
// we're still here - export successfully completed. Write the file.
|
// we're still here - export successfully completed. Write the file.
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
|
||||||
|
}
|
||||||
|
|
||||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ corresponding preprocessor flag to selectively disable steps.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include "AssimpPCH.h"
|
||||||
|
#include "ProcessHelper.h"
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
|
||||||
# include "CalcTangentsProcess.h"
|
# include "CalcTangentsProcess.h"
|
||||||
|
@ -215,7 +216,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
|
||||||
out.push_back( new FlipWindingOrderProcess());
|
out.push_back( new FlipWindingOrderProcess());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_DEBONE_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
|
||||||
out.push_back( new DeboneProcess());
|
out.push_back( new DeboneProcess());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
|
||||||
|
|
|
@ -379,8 +379,7 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
|
||||||
light->mColorSpecular = light->mColorDiffuse;
|
light->mColorSpecular = light->mColorDiffuse;
|
||||||
|
|
||||||
|
|
||||||
// We don't need the rest, but we need to know where
|
// We don't need the rest, but we need to know where this chunk ends.
|
||||||
// this fucking chunk ends.
|
|
||||||
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
|
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
|
||||||
|
|
||||||
// skip the background file name
|
// skip the background file name
|
||||||
|
|
|
@ -525,7 +525,7 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t /*line*/, const char*
|
||||||
--skip_depth;
|
--skip_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip_depth == 1 && *a=='#') {
|
if (skip_depth >= 1 && *a=='#') {
|
||||||
const char* tmp;
|
const char* tmp;
|
||||||
const int64_t num = static_cast<int64_t>( strtoul10_64(a+1,&tmp) );
|
const int64_t num = static_cast<int64_t>( strtoul10_64(a+1,&tmp) );
|
||||||
db.MarkRef(num,id);
|
db.MarkRef(num,id);
|
||||||
|
|
|
@ -57,6 +57,23 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
|
|
||||||
// we're still here - export successfully completed. Write the file.
|
// we're still here - export successfully completed. Write the file.
|
||||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
|
}
|
||||||
|
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
||||||
|
{
|
||||||
|
// invoke the exporter
|
||||||
|
STLExporter exporter(pFile, pScene, true);
|
||||||
|
|
||||||
|
// we're still here - export successfully completed. Write the file.
|
||||||
|
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||||
|
if(outfile == NULL) {
|
||||||
|
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
|
||||||
|
}
|
||||||
|
|
||||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +81,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
|
STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary)
|
||||||
: filename(_filename)
|
: filename(_filename)
|
||||||
, pScene(pScene)
|
, pScene(pScene)
|
||||||
, endl("\n")
|
, endl("\n")
|
||||||
|
@ -72,14 +89,31 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene)
|
||||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
const std::locale& l = std::locale("C");
|
const std::locale& l = std::locale("C");
|
||||||
mOutput.imbue(l);
|
mOutput.imbue(l);
|
||||||
|
if (binary) {
|
||||||
const std::string& name = "AssimpScene";
|
char buf[80] = {0} ;
|
||||||
|
buf[0] = 'A'; buf[1] = 's'; buf[2] = 's'; buf[3] = 'i'; buf[4] = 'm'; buf[5] = 'p';
|
||||||
|
buf[6] = 'S'; buf[7] = 'c'; buf[8] = 'e'; buf[9] = 'n'; buf[10] = 'e';
|
||||||
|
mOutput.write(buf, 80);
|
||||||
|
unsigned int meshnum = 0;
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
for (unsigned int j = 0; j < pScene->mMeshes[i]->mNumFaces; ++j) {
|
||||||
|
meshnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AI_SWAP4(meshnum);
|
||||||
|
mOutput.write((char *)&meshnum, 4);
|
||||||
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
WriteMeshBinary(pScene->mMeshes[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const std::string& name = "AssimpScene";
|
||||||
|
|
||||||
mOutput << "solid " << name << endl;
|
mOutput << "solid " << name << endl;
|
||||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
WriteMesh(pScene->mMeshes[i]);
|
WriteMesh(pScene->mMeshes[i]);
|
||||||
|
}
|
||||||
|
mOutput << "endsolid " << name << endl;
|
||||||
}
|
}
|
||||||
mOutput << "endsolid " << name << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -109,4 +143,31 @@ void STLExporter :: WriteMesh(const aiMesh* m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void STLExporter :: WriteMeshBinary(const aiMesh* m)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
|
const aiFace& f = m->mFaces[i];
|
||||||
|
// we need per-face normals. We specified aiProcess_GenNormals as pre-requisite for this exporter,
|
||||||
|
// but nonetheless we have to expect per-vertex normals.
|
||||||
|
aiVector3D nor;
|
||||||
|
if (m->mNormals) {
|
||||||
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
|
nor += m->mNormals[f.mIndices[a]];
|
||||||
|
}
|
||||||
|
nor.Normalize();
|
||||||
|
}
|
||||||
|
float nx = nor.x, ny = nor.y, nz = nor.z;
|
||||||
|
AI_SWAP4(nx); AI_SWAP4(ny); AI_SWAP4(nz);
|
||||||
|
mOutput.write((char *)&nx, 4); mOutput.write((char *)&ny, 4); mOutput.write((char *)&nz, 4);
|
||||||
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
|
const aiVector3D& v = m->mVertices[f.mIndices[a]];
|
||||||
|
float vx = v.x, vy = v.y, vz = v.z;
|
||||||
|
AI_SWAP4(vx); AI_SWAP4(vy); AI_SWAP4(vz);
|
||||||
|
mOutput.write((char *)&vx, 4); mOutput.write((char *)&vy, 4); mOutput.write((char *)&vz, 4);
|
||||||
|
}
|
||||||
|
char dummy[2] = {0};
|
||||||
|
mOutput.write(dummy, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,7 +59,7 @@ class STLExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// Constructor for a specific scene to export
|
||||||
STLExporter(const char* filename, const aiScene* pScene);
|
STLExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void WriteMesh(const aiMesh* m);
|
void WriteMesh(const aiMesh* m);
|
||||||
|
void WriteMeshBinary(const aiMesh* m);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"Stereolithography (STL) Importer",
|
"Stereolithography (STL) Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -64,6 +65,34 @@ static const aiImporterDesc desc = {
|
||||||
"stl"
|
"stl"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A valid binary STL buffer should consist of the following elements, in order:
|
||||||
|
// 1) 80 byte header
|
||||||
|
// 2) 4 byte face count
|
||||||
|
// 3) 50 bytes per face
|
||||||
|
bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (fileSize < 84)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
|
||||||
|
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
||||||
|
|
||||||
|
return expectedBinaryFileSize == fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
|
||||||
|
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
|
||||||
|
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
|
||||||
|
bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||||
|
if (IsBinarySTL(buffer, fileSize))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fileSize < 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return strncmp(buffer, "solid", 5) == 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
STLImporter::STLImporter()
|
STLImporter::STLImporter()
|
||||||
|
@ -136,12 +165,13 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
bool bMatClr = false;
|
bool bMatClr = false;
|
||||||
|
|
||||||
// check whether the file starts with 'solid' -
|
if (IsBinarySTL(mBuffer, fileSize)) {
|
||||||
// in this case we can simply assume it IS a text file. finished.
|
bMatClr = LoadBinaryFile();
|
||||||
if (!::strncmp(mBuffer,"solid",5)) {
|
} else if (IsAsciiSTL(mBuffer, fileSize)) {
|
||||||
LoadASCIIFile();
|
LoadASCIIFile();
|
||||||
|
} else {
|
||||||
|
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
||||||
}
|
}
|
||||||
else bMatClr = LoadBinaryFile();
|
|
||||||
|
|
||||||
// now copy faces
|
// now copy faces
|
||||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
@ -384,7 +414,7 @@ bool STLImporter::LoadBinaryFile()
|
||||||
}
|
}
|
||||||
aiColor4D* clr = &pMesh->mColors[0][i*3];
|
aiColor4D* clr = &pMesh->mColors[0][i*3];
|
||||||
clr->a = 1.0f;
|
clr->a = 1.0f;
|
||||||
if (bIsMaterialise) // fuck, this is reversed
|
if (bIsMaterialise) // this is reversed
|
||||||
{
|
{
|
||||||
clr->r = (color & 0x31u) / 31.0f;
|
clr->r = (color & 0x31u) / 31.0f;
|
||||||
clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
|
clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
|
||||||
|
|
|
@ -193,7 +193,7 @@ public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Increase the file pointer (relative seeking) */
|
/** Increase the file pointer (relative seeking) */
|
||||||
void IncPtr(int plus) {
|
void IncPtr(size_t plus) {
|
||||||
current += plus;
|
current += plus;
|
||||||
if (current > limit) {
|
if (current > limit) {
|
||||||
throw DeadlyImportError("End of file or read limit was reached");
|
throw DeadlyImportError("End of file or read limit was reached");
|
||||||
|
|
|
@ -90,6 +90,19 @@ public:
|
||||||
underlying << sin;
|
underlying << sin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The problem described here:
|
||||||
|
// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
|
||||||
|
// can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries
|
||||||
|
// being bound to const ref& function parameters. Copying streams is not permitted, though.
|
||||||
|
// This workaround avoids this by manually specifying a copy ctor.
|
||||||
|
#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
|
basic_formatter(const basic_formatter& other) {
|
||||||
|
underlying << (string)other;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
operator string () const {
|
operator string () const {
|
||||||
|
|
|
@ -82,7 +82,7 @@ protected:
|
||||||
/** Report a validation error. This will throw an exception,
|
/** Report a validation error. This will throw an exception,
|
||||||
* control won't return.
|
* control won't return.
|
||||||
* @param msg Format string for sprintf().*/
|
* @param msg Format string for sprintf().*/
|
||||||
AI_WONT_RETURN void ReportError(const char* msg,...);
|
AI_WONT_RETURN void ReportError(const char* msg,...) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -77,8 +77,11 @@ struct free_it
|
||||||
void* free;
|
void* free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
|
||||||
template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: ";
|
template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: ";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"XGL Importer",
|
"XGL Importer",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define __FAST_A_TO_F_H_INCLUDED__
|
#define __FAST_A_TO_F_H_INCLUDED__
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,6 +164,8 @@ int Triangle::Index(const Point* p)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
||||||
|
@ -223,6 +225,8 @@ Point* Triangle::PointCW(Point& point)
|
||||||
return points_[1];
|
return points_[1];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The point counter-clockwise to given point
|
// The point counter-clockwise to given point
|
||||||
|
@ -236,6 +240,8 @@ Point* Triangle::PointCCW(Point& point)
|
||||||
return points_[0];
|
return points_[0];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The neighbor clockwise to given point
|
// The neighbor clockwise to given point
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
|
@ -137,8 +138,8 @@ struct Edge {
|
||||||
p = &p2;
|
p = &p2;
|
||||||
} else if (p1.x == p2.x) {
|
} else if (p1.x == p2.x) {
|
||||||
// Repeat points
|
// Repeat points
|
||||||
// ASSIMP_CHANGE (aramis_acg)
|
// ASSIMP_CHANGE (aramis_acg)
|
||||||
throw std::runtime_error("repeat points");
|
throw std::runtime_error(std::string("repeat points"));
|
||||||
//assert(false);
|
//assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1421,6 +1421,10 @@ IFC support is new and considered experimental. Please report any bugs you may e
|
||||||
- The implementation knows only about IFC2X3 and applies this rule set to all models it encounters,
|
- The implementation knows only about IFC2X3 and applies this rule set to all models it encounters,
|
||||||
regardless of their actual version. Loading of older or newer files may fail with parsing errors.
|
regardless of their actual version. Loading of older or newer files may fail with parsing errors.
|
||||||
|
|
||||||
|
@subsection ifc_metadata Metadata
|
||||||
|
|
||||||
|
IFC file properties (IfcPropertySet) are kept as per-node metadata, see aiNode::mMetaData.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
@section ogre Ogre
|
@section ogre Ogre
|
||||||
*ATTENTION*: The Ogre-Loader is currently under development, many things have changed after this documentation was written, but they are not final enough to rewrite the documentation. So things may have changed by now!
|
*ATTENTION*: The Ogre-Loader is currently under development, many things have changed after this documentation was written, but they are not final enough to rewrite the documentation. So things may have changed by now!
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
# pragma pack(push,1)
|
# pragma pack(push,1)
|
||||||
# define PACK_STRUCT
|
# define PACK_STRUCT
|
||||||
#elif defined( __GNUC__ )
|
#elif defined( __GNUC__ )
|
||||||
# define PACK_STRUCT __attribute__((packed))
|
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
||||||
#else
|
#else
|
||||||
# error Compiler not supported
|
# error Compiler not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
class ExporterPimpl;
|
class ExporterPimpl;
|
||||||
|
class IOSystem;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -409,11 +409,12 @@ public:
|
||||||
* instance. Use GetOrphanedScene() to take ownership of it.
|
* instance. Use GetOrphanedScene() to take ownership of it.
|
||||||
*
|
*
|
||||||
* @note This is a straightforward way to decode models from memory
|
* @note This is a straightforward way to decode models from memory
|
||||||
* buffers, but it doesn't handle model formats spreading their
|
* buffers, but it doesn't handle model formats that spread their
|
||||||
* data across multiple files or even directories. Examples include
|
* data across multiple files or even directories. Examples include
|
||||||
* OBJ or MD3, which outsource parts of their material stuff into
|
* OBJ or MD3, which outsource parts of their material info into
|
||||||
* external scripts. If you need the full functionality, provide
|
* external scripts. If you need full functionality, provide
|
||||||
* a custom IOSystem to make Assimp find these files.
|
* a custom IOSystem to make Assimp find these files and use
|
||||||
|
* the regular ReadFile() API.
|
||||||
*/
|
*/
|
||||||
const aiScene* ReadFileFromMemory(
|
const aiScene* ReadFileFromMemory(
|
||||||
const void* pBuffer,
|
const void* pBuffer,
|
||||||
|
|
|
@ -208,7 +208,7 @@ enum aiAnimBehaviour
|
||||||
/** This value is not used, it is just here to force the
|
/** This value is not used, it is just here to force the
|
||||||
* the compiler to map this enum to a 32 Bit integer */
|
* the compiler to map this enum to a 32 Bit integer */
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiAnimBehaviour_Force32Bit = 0x8fffffff
|
_aiAnimBehaviour_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -170,11 +170,13 @@ ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties(
|
||||||
* Check the return value, and you'll know ...
|
* Check the return value, and you'll know ...
|
||||||
* @return A pointer to the imported data, NULL if the import failed.
|
* @return A pointer to the imported data, NULL if the import failed.
|
||||||
*
|
*
|
||||||
* @note This is a straightforward way to decode models from memory buffers, but it
|
* @note This is a straightforward way to decode models from memory
|
||||||
* doesn't handle model formats spreading their data across multiple files or even
|
* buffers, but it doesn't handle model formats that spread their
|
||||||
* directories. Examples include OBJ or MD3, which outsource parts of their material
|
* data across multiple files or even directories. Examples include
|
||||||
* stuff into external scripts. If you need the full functionality, provide a custom
|
* OBJ or MD3, which outsource parts of their material info into
|
||||||
* IOSystem to make Assimp find these files.
|
* external scripts. If you need full functionality, provide
|
||||||
|
* a custom IOSystem to make Assimp find these files and use
|
||||||
|
* the regular aiImportFileEx()/aiImportFileExWithProperties() API.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory(
|
ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory(
|
||||||
const char* pBuffer,
|
const char* pBuffer,
|
||||||
|
|
|
@ -403,7 +403,7 @@ enum aiComponent
|
||||||
* use the #aiProcess_OptimizeGraph step to do this */
|
* use the #aiProcess_OptimizeGraph step to do this */
|
||||||
aiComponent_LIGHTS = 0x100,
|
aiComponent_LIGHTS = 0x100,
|
||||||
|
|
||||||
/** Removes all light sources (aiScene::mCameras).
|
/** Removes all cameras (aiScene::mCameras).
|
||||||
* The corresponding scenegraph nodes are NOT removed.
|
* The corresponding scenegraph nodes are NOT removed.
|
||||||
* use the #aiProcess_OptimizeGraph step to do this */
|
* use the #aiProcess_OptimizeGraph step to do this */
|
||||||
aiComponent_CAMERAS = 0x200,
|
aiComponent_CAMERAS = 0x200,
|
||||||
|
@ -841,4 +841,6 @@ enum aiComponent
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
|
#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
|
||||||
|
|
||||||
#endif // !! AI_CONFIG_H_INC
|
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
|
||||||
|
|
||||||
|
#endif // !! AI_CONFIG_H_INC
|
||||||
|
|
|
@ -60,9 +60,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Other (mixed) configuration switches are listed here:
|
* Other (mixed) configuration switches are listed here:
|
||||||
* ASSIMP_BUILD_NO_COMPRESSED_X
|
* ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
* - Disable support for compressed X files
|
* - Disable support for compressed X files (zip)
|
||||||
* ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
* ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
* - Disable support for compressed Blender files*/
|
* - Disable support for compressed Blender files (zip)
|
||||||
|
* ASSIMP_BUILD_NO_COMPRESSED_IFC
|
||||||
|
* - Disable support for IFCZIP files (unzip)
|
||||||
|
*/
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
|
@ -71,6 +74,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
# define ASSIMP_BUILD_NEED_Z_INFLATE
|
# define ASSIMP_BUILD_NEED_Z_INFLATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
|
||||||
|
# define ASSIMP_BUILD_NEED_Z_INFLATE
|
||||||
|
# define ASSIMP_BUILD_NEED_UNZIP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||||
|
# define ASSIMP_BUILD_NEED_Z_INFLATE
|
||||||
|
# define ASSIMP_BUILD_NEED_UNZIP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -149,6 +162,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# define AI_FORCE_INLINE inline
|
# define AI_FORCE_INLINE inline
|
||||||
#endif // (defined _MSC_VER)
|
#endif // (defined _MSC_VER)
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
# define AI_WONT_RETURN_SUFFIX __attribute__((analyzer_noreturn))
|
||||||
|
#else
|
||||||
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
|
#endif // (defined __clang__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
|
/* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
|
||||||
* in doxydocs.
|
* in doxydocs.
|
||||||
|
|
|
@ -80,7 +80,7 @@ enum aiLightSourceType
|
||||||
* compiler to map this enum to a 32 Bit integer.
|
* compiler to map this enum to a 32 Bit integer.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiLightSource_Force32Bit = 0x9fffffff
|
_aiLightSource_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ enum aiTextureOp
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiTextureOp_Force32Bit = 0x9fffffff
|
_aiTextureOp_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -136,7 +136,7 @@ enum aiTextureMapMode
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiTextureMapMode_Force32Bit = 0x9fffffff
|
_aiTextureMapMode_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -181,7 +181,7 @@ enum aiTextureMapping
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiTextureMapping_Force32Bit = 0x9fffffff
|
_aiTextureMapping_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -301,7 +301,7 @@ enum aiTextureType
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiTextureType_Force32Bit = 0x9fffffff
|
_aiTextureType_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -379,7 +379,7 @@ enum aiShadingMode
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiShadingMode_Force32Bit = 0x9fffffff
|
_aiShadingMode_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -425,7 +425,7 @@ enum aiTextureFlags
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiTextureFlags_Force32Bit = 0x9fffffff
|
_aiTextureFlags_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -474,7 +474,7 @@ enum aiBlendMode
|
||||||
* 32 Bit integers to represent this enum.
|
* 32 Bit integers to represent this enum.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiBlendMode_Force32Bit = 0x9fffffff
|
_aiBlendMode_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
//! @endcond
|
//! @endcond
|
||||||
};
|
};
|
||||||
|
@ -568,7 +568,7 @@ enum aiPropertyTypeInfo
|
||||||
* compiler to map this enum to a 32 Bit integer.
|
* compiler to map this enum to a 32 Bit integer.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiPTI_Force32Bit = 0x9fffffff
|
_aiPTI_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -631,9 +631,13 @@ struct aiMaterialProperty
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
aiMaterialProperty() {
|
aiMaterialProperty()
|
||||||
mData = NULL;
|
: mSemantic( 0 )
|
||||||
mIndex = mSemantic = 0;
|
, mIndex( 0 )
|
||||||
|
, mDataLength( 0 )
|
||||||
|
, mType( aiPTI_Float )
|
||||||
|
, mData( NULL )
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~aiMaterialProperty() {
|
~aiMaterialProperty() {
|
||||||
|
@ -657,7 +661,11 @@ struct aiMaterialProperty
|
||||||
* have to stick with the aiMaterialGetXXX family of unbound functions.
|
* have to stick with the aiMaterialGetXXX family of unbound functions.
|
||||||
* The library defines a set of standard keys (AI_MATKEY_XXX).
|
* The library defines a set of standard keys (AI_MATKEY_XXX).
|
||||||
*/
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
struct ASSIMP_API aiMaterial
|
struct ASSIMP_API aiMaterial
|
||||||
|
#else
|
||||||
|
struct aiMaterial
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -176,8 +176,6 @@ inline aiReturn aiMaterial::Get<aiString>(const char* pKey,unsigned int type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<class TYPE>
|
template<class TYPE>
|
||||||
aiReturn aiMaterial::AddProperty (const TYPE* pInput,
|
aiReturn aiMaterial::AddProperty (const TYPE* pInput,
|
||||||
|
@ -269,8 +267,6 @@ inline aiReturn aiMaterial::AddProperty<int> (const int* pInput,
|
||||||
pKey,type,index,aiPTI_Integer);
|
pKey,type,index,aiPTI_Integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
||||||
#endif //! AI_MATERIAL_INL_INC
|
#endif //! AI_MATERIAL_INL_INC
|
||||||
|
|
|
@ -135,8 +135,9 @@ struct aiFace
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
aiFace()
|
aiFace()
|
||||||
|
: mNumIndices( 0 )
|
||||||
|
, mIndices( NULL )
|
||||||
{
|
{
|
||||||
mNumIndices = 0; mIndices = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Default destructor. Delete the index array
|
//! Default destructor. Delete the index array
|
||||||
|
@ -147,21 +148,26 @@ struct aiFace
|
||||||
|
|
||||||
//! Copy constructor. Copy the index array
|
//! Copy constructor. Copy the index array
|
||||||
aiFace( const aiFace& o)
|
aiFace( const aiFace& o)
|
||||||
|
: mIndices( NULL )
|
||||||
{
|
{
|
||||||
mIndices = NULL;
|
|
||||||
*this = o;
|
*this = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Assignment operator. Copy the index array
|
//! Assignment operator. Copy the index array
|
||||||
const aiFace& operator = ( const aiFace& o)
|
aiFace& operator = ( const aiFace& o)
|
||||||
{
|
{
|
||||||
if (&o == this)
|
if (&o == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
delete[] mIndices;
|
delete[] mIndices;
|
||||||
mNumIndices = o.mNumIndices;
|
mNumIndices = o.mNumIndices;
|
||||||
mIndices = new unsigned int[mNumIndices];
|
if (mNumIndices) {
|
||||||
::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
|
mIndices = new unsigned int[mNumIndices];
|
||||||
|
::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mIndices = NULL;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,17 +249,17 @@ struct aiBone
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
aiBone()
|
aiBone()
|
||||||
|
: mNumWeights( 0 )
|
||||||
|
, mWeights( NULL )
|
||||||
{
|
{
|
||||||
mNumWeights = 0; mWeights = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Copy constructor
|
//! Copy constructor
|
||||||
aiBone(const aiBone& other)
|
aiBone(const aiBone& other)
|
||||||
|
: mName( other.mName )
|
||||||
|
, mNumWeights( other.mNumWeights )
|
||||||
|
, mOffsetMatrix( other.mOffsetMatrix )
|
||||||
{
|
{
|
||||||
mNumWeights = other.mNumWeights;
|
|
||||||
mOffsetMatrix = other.mOffsetMatrix;
|
|
||||||
mName = other.mName;
|
|
||||||
|
|
||||||
if (other.mWeights && other.mNumWeights)
|
if (other.mWeights && other.mNumWeights)
|
||||||
{
|
{
|
||||||
mWeights = new aiVertexWeight[mNumWeights];
|
mWeights = new aiVertexWeight[mNumWeights];
|
||||||
|
@ -314,7 +320,7 @@ enum aiPrimitiveType
|
||||||
* compiler to map this enum to a 32 Bit integer.
|
* compiler to map this enum to a 32 Bit integer.
|
||||||
*/
|
*/
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
_aiPrimitiveType_Force32Bit = 0x9fffffff
|
_aiPrimitiveType_Force32Bit = INT_MAX
|
||||||
#endif
|
#endif
|
||||||
}; //! enum aiPrimitiveType
|
}; //! enum aiPrimitiveType
|
||||||
|
|
||||||
|
@ -373,10 +379,11 @@ struct aiAnimMesh
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
aiAnimMesh()
|
aiAnimMesh()
|
||||||
: mVertices()
|
: mVertices( NULL )
|
||||||
, mNormals()
|
, mNormals( NULL )
|
||||||
, mTangents()
|
, mTangents( NULL )
|
||||||
, mBitangents()
|
, mBitangents( NULL )
|
||||||
|
, mNumVertices( 0 )
|
||||||
{
|
{
|
||||||
// fixme consider moving this to the ctor initializer list as well
|
// fixme consider moving this to the ctor initializer list as well
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
|
||||||
|
@ -604,29 +611,28 @@ struct aiMesh
|
||||||
|
|
||||||
//! Default constructor. Initializes all members to 0
|
//! Default constructor. Initializes all members to 0
|
||||||
aiMesh()
|
aiMesh()
|
||||||
|
: mPrimitiveTypes( 0 )
|
||||||
|
, mNumVertices( 0 )
|
||||||
|
, mNumFaces( 0 )
|
||||||
|
, mVertices( NULL )
|
||||||
|
, mNormals( NULL )
|
||||||
|
, mTangents( NULL )
|
||||||
|
, mBitangents( NULL )
|
||||||
|
, mFaces( NULL )
|
||||||
|
, mNumBones( 0 )
|
||||||
|
, mBones( 0 )
|
||||||
|
, mMaterialIndex( 0 )
|
||||||
|
, mNumAnimMeshes( 0 )
|
||||||
|
, mAnimMeshes( NULL )
|
||||||
{
|
{
|
||||||
mNumVertices = 0;
|
|
||||||
mNumFaces = 0;
|
|
||||||
|
|
||||||
mNumAnimMeshes = 0;
|
|
||||||
|
|
||||||
mPrimitiveTypes = 0;
|
|
||||||
mVertices = NULL; mFaces = NULL;
|
|
||||||
mNormals = NULL; mTangents = NULL;
|
|
||||||
mBitangents = NULL;
|
|
||||||
mAnimMeshes = NULL;
|
|
||||||
|
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
||||||
{
|
{
|
||||||
mNumUVComponents[a] = 0;
|
mNumUVComponents[a] = 0;
|
||||||
mTextureCoords[a] = NULL;
|
mTextureCoords[a] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
||||||
mColors[a] = NULL;
|
mColors[a] = NULL;
|
||||||
mNumBones = 0; mBones = NULL;
|
|
||||||
mMaterialIndex = 0;
|
|
||||||
mNumAnimMeshes = 0;
|
|
||||||
mAnimMeshes = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Deletes all storage allocated for the mesh
|
//! Deletes all storage allocated for the mesh
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2012, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file metadata.h
|
||||||
|
* @brief Defines the data structures for holding node meta information.
|
||||||
|
*/
|
||||||
|
#ifndef __AI_METADATA_H_INC__
|
||||||
|
#define __AI_METADATA_H_INC__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Container for holding metadata.
|
||||||
|
*
|
||||||
|
* Metadata is a key-value store using string keys and values.
|
||||||
|
*/
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
struct aiMetadata
|
||||||
|
{
|
||||||
|
/** Length of the mKeys and mValues arrays, respectively */
|
||||||
|
unsigned int mNumProperties;
|
||||||
|
|
||||||
|
/** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
|
||||||
|
C_STRUCT aiString** mKeys;
|
||||||
|
|
||||||
|
/** Arrays of values, may not be NULL. Entries in this array may be NULL if the
|
||||||
|
* corresponding property key has no assigned value. */
|
||||||
|
C_STRUCT aiString** mValues;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
aiMetadata()
|
||||||
|
{
|
||||||
|
// set all members to zero by default
|
||||||
|
mKeys = NULL;
|
||||||
|
mValues = NULL;
|
||||||
|
mNumProperties = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Destructor */
|
||||||
|
~aiMetadata()
|
||||||
|
{
|
||||||
|
if (mKeys && mValues) {
|
||||||
|
for (unsigned i=0; i<mNumProperties; ++i) {
|
||||||
|
if (mKeys[i]) {
|
||||||
|
delete mKeys[i];
|
||||||
|
}
|
||||||
|
if (mValues[i]) {
|
||||||
|
delete mValues[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] mKeys;
|
||||||
|
delete [] mValues;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Get(const aiString& key, aiString& value)
|
||||||
|
{
|
||||||
|
for (unsigned i=0; i<mNumProperties; ++i) {
|
||||||
|
if (mKeys[i] && *mKeys[i]==key) {
|
||||||
|
value=*mValues[i];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} //extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __AI_METADATA_H_INC__
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "anim.h"
|
#include "anim.h"
|
||||||
|
#include "metadata.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** A node in the imported hierarchy.
|
/** A node in the imported hierarchy.
|
||||||
*
|
*
|
||||||
|
@ -71,16 +73,24 @@ struct aiNode
|
||||||
/** The name of the node.
|
/** The name of the node.
|
||||||
*
|
*
|
||||||
* The name might be empty (length of zero) but all nodes which
|
* The name might be empty (length of zero) but all nodes which
|
||||||
* need to be accessed afterwards by bones or anims are usually named.
|
* need to be referenced by either bones or animations are named.
|
||||||
* Multiple nodes may have the same name, but nodes which are accessed
|
* Multiple nodes may have the same name, except for nodes which are referenced
|
||||||
* by bones (see #aiBone and #aiMesh::mBones) *must* be unique.
|
* by bones (see #aiBone and #aiMesh::mBones). Their names *must* be unique.
|
||||||
*
|
*
|
||||||
* Cameras and lights are assigned to a specific node name - if there
|
* Cameras and lights reference a specific node by name - if there
|
||||||
* are multiple nodes with this name, they're assigned to each of them.
|
* are multiple nodes with this name, they are assigned to each of them.
|
||||||
* <br>
|
* <br>
|
||||||
* There are no limitations regarding the characters contained in
|
* There are no limitations with regard to the characters contained in
|
||||||
* this text. You should be able to handle stuff like whitespace, tabs,
|
* the name string as it is usually taken directly from the source file.
|
||||||
* linefeeds, quotation marks, ampersands, ... .
|
*
|
||||||
|
* Implementations should be able to handle tokens such as whitespace, tabs,
|
||||||
|
* line feeds, quotation marks, ampersands etc.
|
||||||
|
*
|
||||||
|
* Sometimes assimp introduces new nodes not present in the source file
|
||||||
|
* into the hierarchy (usually out of necessity because sometimes the
|
||||||
|
* source hierarchy format is simply not compatible). Their names are
|
||||||
|
* surrounded by @verbatim <> @endverbatim e.g.
|
||||||
|
* @verbatim<DummyRootNode> @endverbatim.
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiString mName;
|
C_STRUCT aiString mName;
|
||||||
|
|
||||||
|
@ -102,24 +112,39 @@ struct aiNode
|
||||||
/** The meshes of this node. Each entry is an index into the mesh */
|
/** The meshes of this node. Each entry is an index into the mesh */
|
||||||
unsigned int* mMeshes;
|
unsigned int* mMeshes;
|
||||||
|
|
||||||
|
/** Metadata associated with this node or NULL if there is no metadata.
|
||||||
|
* Whether any metadata is generated depends on the source file format. See the
|
||||||
|
* @link importer_notes @endlink page for more information on every source file
|
||||||
|
* format. Importers that don't document any metadata don't write any.
|
||||||
|
*/
|
||||||
|
C_STRUCT aiMetadata* mMetaData;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
aiNode()
|
aiNode()
|
||||||
{
|
|
||||||
// set all members to zero by default
|
// set all members to zero by default
|
||||||
mParent = NULL;
|
: mName()
|
||||||
mNumChildren = 0; mChildren = NULL;
|
, mParent()
|
||||||
mNumMeshes = 0; mMeshes = NULL;
|
, mNumChildren()
|
||||||
|
, mChildren()
|
||||||
|
, mNumMeshes()
|
||||||
|
, mMeshes()
|
||||||
|
, mMetaData()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Construction from a specific name */
|
/** Construction from a specific name */
|
||||||
aiNode(const std::string& name)
|
aiNode(const std::string& name)
|
||||||
{
|
|
||||||
// set all members to zero by default
|
// set all members to zero by default
|
||||||
mParent = NULL;
|
: mName(name)
|
||||||
mNumChildren = 0; mChildren = NULL;
|
, mParent()
|
||||||
mNumMeshes = 0; mMeshes = NULL;
|
, mNumChildren()
|
||||||
mName = name;
|
, mChildren()
|
||||||
|
, mNumMeshes()
|
||||||
|
, mMeshes()
|
||||||
|
, mMetaData()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
|
@ -134,8 +159,10 @@ struct aiNode
|
||||||
}
|
}
|
||||||
delete [] mChildren;
|
delete [] mChildren;
|
||||||
delete [] mMeshes;
|
delete [] mMeshes;
|
||||||
|
delete mMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Searches for a node with a specific name, beginning at this
|
/** Searches for a node with a specific name, beginning at this
|
||||||
* nodes. Normally you will call this method on the root node
|
* nodes. Normally you will call this method on the root node
|
||||||
* of the scene.
|
* of the scene.
|
||||||
|
@ -143,22 +170,45 @@ struct aiNode
|
||||||
* @param name Name to search for
|
* @param name Name to search for
|
||||||
* @return NULL or a valid Node if the search was successful.
|
* @return NULL or a valid Node if the search was successful.
|
||||||
*/
|
*/
|
||||||
|
inline const aiNode* FindNode(const aiString& name) const
|
||||||
|
{
|
||||||
|
return FindNode(name.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline aiNode* FindNode(const aiString& name)
|
inline aiNode* FindNode(const aiString& name)
|
||||||
{
|
{
|
||||||
return FindNode(name.data);
|
return FindNode(name.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @override
|
/** @override
|
||||||
*/
|
*/
|
||||||
inline aiNode* FindNode(const char* name)
|
inline const aiNode* FindNode(const char* name) const
|
||||||
{
|
{
|
||||||
if (!::strcmp( mName.data,name))return this;
|
if (!::strcmp( mName.data,name))return this;
|
||||||
for (unsigned int i = 0; i < mNumChildren;++i)
|
for (unsigned int i = 0; i < mNumChildren;++i)
|
||||||
{
|
{
|
||||||
aiNode* p = mChildren[i]->FindNode(name);
|
const aiNode* const p = mChildren[i]->FindNode(name);
|
||||||
if (p)return p;
|
if (p) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// there is definitely no sub node with this name
|
// there is definitely no sub-node with this name
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline aiNode* FindNode(const char* name)
|
||||||
|
{
|
||||||
|
if (!::strcmp( mName.data,name))return this;
|
||||||
|
for (unsigned int i = 0; i < mNumChildren;++i)
|
||||||
|
{
|
||||||
|
aiNode* const p = mChildren[i]->FindNode(name);
|
||||||
|
if (p) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// there is definitely no sub-node with this name
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
// Our compile configuration
|
// Our compile configuration
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
|
@ -25,7 +25,7 @@ substituted by assertions ...):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
from pyassimp.core import *
|
from pyassimp import *
|
||||||
scene = load('hello.3ds')
|
scene = load('hello.3ds')
|
||||||
|
|
||||||
assert len(scene.meshes)
|
assert len(scene.meshes)
|
||||||
|
@ -44,7 +44,7 @@ scene:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
from pyassimp.core import *
|
from pyassimp import *
|
||||||
scene = load('hello.3ds')
|
scene = load('hello.3ds')
|
||||||
|
|
||||||
for c in scene.rootnode.children:
|
for c in scene.rootnode.children:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from .core import *
|
|
@ -58,14 +58,14 @@ def make_tuple(ai_obj, type = None):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def call_init(obj, caller = None):
|
def call_init(obj, caller = None):
|
||||||
# init children
|
# init children
|
||||||
if hasattr(obj, '_init'):
|
if helper.hasattr_silent(obj, '_init'):
|
||||||
obj._init(parent = caller)
|
obj._init(parent = caller)
|
||||||
|
|
||||||
# pointers
|
# pointers
|
||||||
elif hasattr(obj, 'contents'):
|
elif helper.hasattr_silent(obj, 'contents'):
|
||||||
if hasattr(obj.contents, '_init'):
|
if helper.hasattr_silent(obj.contents, '_init'):
|
||||||
obj.contents._init(target = obj, parent = caller)
|
obj.contents._init(target = obj, parent = caller)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ def _init(self, target = None, parent = None):
|
||||||
:param target: set the object which receive the added methods. Useful when manipulating
|
:param target: set the object which receive the added methods. Useful when manipulating
|
||||||
pointers, to skip the intermediate 'contents' deferencing.
|
pointers, to skip the intermediate 'contents' deferencing.
|
||||||
"""
|
"""
|
||||||
if hasattr(self, '_is_init'):
|
if helper.hasattr_silent(self, '_is_init'):
|
||||||
return self
|
return self
|
||||||
self._is_init = True
|
self._is_init = True
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ def _init(self, target = None, parent = None):
|
||||||
|
|
||||||
|
|
||||||
if isinstance(obj, structs.String):
|
if isinstance(obj, structs.String):
|
||||||
setattr(target, 'name', str(obj.data))
|
setattr(target, 'name', obj.data.decode("utf-8"))
|
||||||
setattr(target.__class__, '__repr__', lambda x: str(x.__class__) + "(" + x.name + ")")
|
setattr(target.__class__, '__repr__', lambda x: str(x.__class__) + "(" + x.name + ")")
|
||||||
setattr(target.__class__, '__str__', lambda x: x.name)
|
setattr(target.__class__, '__str__', lambda x: x.name)
|
||||||
continue
|
continue
|
||||||
|
@ -121,7 +121,7 @@ def _init(self, target = None, parent = None):
|
||||||
logger.debug("Added a parent as self." + name)
|
logger.debug("Added a parent as self." + name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if hasattr(self, 'mNum' + m[1:]):
|
if helper.hasattr_silent(self, 'mNum' + m[1:]):
|
||||||
|
|
||||||
length = getattr(self, 'mNum' + m[1:])
|
length = getattr(self, 'mNum' + m[1:])
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ def _finalize_mesh(mesh, target):
|
||||||
data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32)
|
data = numpy.array([make_tuple(getattr(mesh, name)[i]) for i in range(nb_vertices)], dtype=numpy.float32)
|
||||||
setattr(target, name[1:].lower(), data)
|
setattr(target, name[1:].lower(), data)
|
||||||
else:
|
else:
|
||||||
setattr(target, name[1:].lower(), [])
|
setattr(target, name[1:].lower(), numpy.array([], dtype="float32"))
|
||||||
|
|
||||||
def fillarray(name):
|
def fillarray(name):
|
||||||
mAttr = getattr(mesh, name)
|
mAttr = getattr(mesh, name)
|
||||||
|
@ -336,6 +336,27 @@ def _finalize_mesh(mesh, target):
|
||||||
faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32)
|
faces = numpy.array([f.indices for f in target.faces], dtype=numpy.int32)
|
||||||
setattr(target, 'faces', faces)
|
setattr(target, 'faces', faces)
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyGetter(dict):
|
||||||
|
def __getitem__(self, key):
|
||||||
|
semantic = 0
|
||||||
|
if isinstance(key, tuple):
|
||||||
|
key, semantic = key
|
||||||
|
|
||||||
|
return dict.__getitem__(self, (key, semantic))
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
for k in dict.keys(self):
|
||||||
|
yield k[0]
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self.keys()
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
for k, v in dict.items(self):
|
||||||
|
yield k[0], v
|
||||||
|
|
||||||
|
|
||||||
def _get_properties(properties, length):
|
def _get_properties(properties, length):
|
||||||
"""
|
"""
|
||||||
Convenience Function to get the material properties as a dict
|
Convenience Function to get the material properties as a dict
|
||||||
|
@ -346,7 +367,7 @@ def _get_properties(properties, length):
|
||||||
for p in [properties[i] for i in range(length)]:
|
for p in [properties[i] for i in range(length)]:
|
||||||
#the name
|
#the name
|
||||||
p = p.contents
|
p = p.contents
|
||||||
key = str(p.mKey.data).split('.')[1]
|
key = (str(p.mKey.data.decode("utf-8")).split('.')[1], p.mSemantic)
|
||||||
|
|
||||||
#the data
|
#the data
|
||||||
from ctypes import POINTER, cast, c_int, c_float, sizeof
|
from ctypes import POINTER, cast, c_int, c_float, sizeof
|
||||||
|
@ -354,7 +375,7 @@ def _get_properties(properties, length):
|
||||||
arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
|
arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
|
||||||
value = [x for x in arr]
|
value = [x for x in arr]
|
||||||
elif p.mType == 3: #string can't be an array
|
elif p.mType == 3: #string can't be an array
|
||||||
value = cast(p.mData, POINTER(structs.String)).contents.data
|
value = cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data.decode("utf-8")
|
||||||
elif p.mType == 4:
|
elif p.mType == 4:
|
||||||
arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents
|
arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents
|
||||||
value = [x for x in arr]
|
value = [x for x in arr]
|
||||||
|
@ -366,7 +387,7 @@ def _get_properties(properties, length):
|
||||||
|
|
||||||
result[key] = value
|
result[key] = value
|
||||||
|
|
||||||
return result
|
return PropertyGetter(result)
|
||||||
|
|
||||||
def decompose_matrix(matrix):
|
def decompose_matrix(matrix):
|
||||||
if not isinstance(matrix, structs.Matrix4x4):
|
if not isinstance(matrix, structs.Matrix4x4):
|
||||||
|
|
|
@ -154,5 +154,15 @@ def search_library():
|
||||||
# XXX: take version postfix of the .so on linux?
|
# XXX: take version postfix of the .so on linux?
|
||||||
return res[1:]
|
return res[1:]
|
||||||
|
|
||||||
|
def hasattr_silent(object, name):
|
||||||
|
"""
|
||||||
|
Calls hasttr() with the given parameters and preserves the legacy (pre-Python 3.2)
|
||||||
|
functionality of silently catching exceptions.
|
||||||
|
|
||||||
|
Returns the result of hasatter() or False if an exception was raised.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
return hasattr(object, name)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#-*- coding: UTF-8 -*-
|
#-*- coding: UTF-8 -*-
|
||||||
|
|
||||||
from ctypes import POINTER, c_void_p, c_int, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t
|
from ctypes import POINTER, c_void_p, c_int, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t, c_uint32
|
||||||
|
|
||||||
|
|
||||||
class Vector2D(Structure):
|
class Vector2D(Structure):
|
||||||
|
@ -82,6 +82,26 @@ class String(Structure):
|
||||||
("data", c_char*MAXLEN),
|
("data", c_char*MAXLEN),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class MaterialPropertyString(Structure):
|
||||||
|
"""
|
||||||
|
See 'aiTypes.h' for details.
|
||||||
|
|
||||||
|
The size of length is truncated to 4 bytes on 64-bit platforms when used as a
|
||||||
|
material property (see MaterialSystem.cpp aiMaterial::AddProperty() for details).
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAXLEN = 1024
|
||||||
|
|
||||||
|
_fields_ = [
|
||||||
|
# Binary length of the string excluding the terminal 0. This is NOT the
|
||||||
|
# logical length of strings containing UTF-8 multibyte sequences! It's
|
||||||
|
# the number of bytes from the beginning of the string to its end.
|
||||||
|
("length", c_uint32),
|
||||||
|
|
||||||
|
# String buffer. Size limit is MAXLEN
|
||||||
|
("data", c_char*MAXLEN),
|
||||||
|
]
|
||||||
|
|
||||||
class MemoryInfo(Structure):
|
class MemoryInfo(Structure):
|
||||||
"""
|
"""
|
||||||
See 'aiTypes.h' for details.
|
See 'aiTypes.h' for details.
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
#-*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
This module demonstrates the functionality of PyAssimp.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import pyassimp.core as pyassimp
|
|
||||||
import os, sys
|
|
||||||
|
|
||||||
#get a model out of assimp's test-data if none is provided on the command line
|
|
||||||
DEFAULT_MODEL = os.path.join(os.path.dirname(__file__),
|
|
||||||
"..", "..",
|
|
||||||
"test", "models", "MDL", "MDL3 (3DGS A4)", "minigun.MDL")
|
|
||||||
|
|
||||||
def recur_node(node,level = 0):
|
|
||||||
print(" " + "\t" * level + "- " + str(node))
|
|
||||||
for child in node.children:
|
|
||||||
recur_node(child, level + 1)
|
|
||||||
|
|
||||||
|
|
||||||
def main(filename=None):
|
|
||||||
filename = filename or DEFAULT_MODEL
|
|
||||||
|
|
||||||
print "Reading model", filename
|
|
||||||
scene = pyassimp.load(filename)
|
|
||||||
|
|
||||||
#the model we load
|
|
||||||
print "MODEL:", filename
|
|
||||||
print
|
|
||||||
|
|
||||||
#write some statistics
|
|
||||||
print "SCENE:"
|
|
||||||
print " meshes:", len(scene.meshes)
|
|
||||||
print " materials:", len(scene.materials)
|
|
||||||
print " textures:", len(scene.textures)
|
|
||||||
print
|
|
||||||
|
|
||||||
print "NODES:"
|
|
||||||
recur_node(scene.rootnode)
|
|
||||||
|
|
||||||
print
|
|
||||||
print "MESHES:"
|
|
||||||
for index, mesh in enumerate(scene.meshes):
|
|
||||||
print " MESH", index+1
|
|
||||||
print " material id:", mesh.materialindex+1
|
|
||||||
print " vertices:", len(mesh.vertices)
|
|
||||||
print " first 3 verts:", mesh.vertices[:3]
|
|
||||||
if len(mesh.normals) > 0:
|
|
||||||
print " first 3 normals:", mesh.normals[:3]
|
|
||||||
else:
|
|
||||||
print " no normals"
|
|
||||||
print " colors:", len(mesh.colors)
|
|
||||||
tc = mesh.texturecoords
|
|
||||||
if len(tc) >= 4:
|
|
||||||
print " texture-coords 1:", len(tc[0]), "first3:", tc[0][:3]
|
|
||||||
print " texture-coords 2:", len(tc[1]), "first3:", tc[1][:3]
|
|
||||||
print " texture-coords 3:", len(tc[2]), "first3:", tc[2][:3]
|
|
||||||
print " texture-coords 4:", len(tc[3]), "first3:", tc[3][:3]
|
|
||||||
elif len(tc) == 0:
|
|
||||||
print " no texture coordinates"
|
|
||||||
else:
|
|
||||||
print " tc is an unexpected number of elements (expect 4, got", len(tc), ")"
|
|
||||||
print " uv-component-count:", len(mesh.numuvcomponents)
|
|
||||||
print " faces:", len(mesh.faces), "first:", [f for f in mesh.faces[:3]]
|
|
||||||
print " bones:", len(mesh.bones), "first:", [str(b) for b in mesh.bones[:3]]
|
|
||||||
print
|
|
||||||
|
|
||||||
print "MATERIALS:"
|
|
||||||
for index, material in enumerate(scene.materials):
|
|
||||||
print(" MATERIAL (id:" + str(index+1) + ")")
|
|
||||||
for key, value in material.properties.items():
|
|
||||||
print " %s: %s" % (key, value)
|
|
||||||
print
|
|
||||||
|
|
||||||
print "TEXTURES:"
|
|
||||||
for index, texture in enumerate(scene.textures):
|
|
||||||
print " TEXTURE", index+1
|
|
||||||
print " width:", texture.width
|
|
||||||
print " height:", texture.height
|
|
||||||
print " hint:", texture.achformathint
|
|
||||||
print " data (size):", len(texture.data)
|
|
||||||
|
|
||||||
# Finally release the model
|
|
||||||
pyassimp.release(scene)
|
|
||||||
|
|
||||||
print "Finished parsing the model."
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main(sys.argv[1] if len(sys.argv)>1 else None)
|
|
|
@ -6,23 +6,25 @@
|
||||||
It make a large use of shaders to illustrate a 'modern' OpenGL pipeline.
|
It make a large use of shaders to illustrate a 'modern' OpenGL pipeline.
|
||||||
|
|
||||||
Based on:
|
Based on:
|
||||||
- pygame + mouselook code from http://3dengine.org/Spectator_%28PyOpenGL%29
|
- pygame + mouselook code from http://3dengine.org/Spectator_%28PyOpenGL%29
|
||||||
- http://www.lighthouse3d.com/tutorials
|
- http://www.lighthouse3d.com/tutorials
|
||||||
- http://www.songho.ca/opengl/gl_transform.html
|
- http://www.songho.ca/opengl/gl_transform.html
|
||||||
- http://code.activestate.com/recipes/325391/
|
- http://code.activestate.com/recipes/325391/
|
||||||
- ASSIMP's C++ SimpleOpenGL viewer
|
- ASSIMP's C++ SimpleOpenGL viewer
|
||||||
|
|
||||||
|
Authors: SĂ©verin Lemaignan, 2012-2013
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger("underworlds.3d_viewer")
|
logger = logging.getLogger("pyassimp")
|
||||||
gllogger = logging.getLogger("OpenGL")
|
gllogger = logging.getLogger("OpenGL")
|
||||||
gllogger.setLevel(logging.WARNING)
|
gllogger.setLevel(logging.WARNING)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
import OpenGL
|
import OpenGL
|
||||||
#OpenGL.ERROR_CHECKING=False
|
OpenGL.ERROR_CHECKING=False
|
||||||
#OpenGL.ERROR_LOGGING = False
|
OpenGL.ERROR_LOGGING = False
|
||||||
#OpenGL.ERROR_ON_COPY = True
|
#OpenGL.ERROR_ON_COPY = True
|
||||||
#OpenGL.FULL_LOGGING = True
|
#OpenGL.FULL_LOGGING = True
|
||||||
from OpenGL.GL import *
|
from OpenGL.GL import *
|
||||||
|
@ -38,7 +40,7 @@ import math, random
|
||||||
import numpy
|
import numpy
|
||||||
from numpy import linalg
|
from numpy import linalg
|
||||||
|
|
||||||
from pyassimp import core as pyassimp
|
import pyassimp
|
||||||
from pyassimp.postprocess import *
|
from pyassimp.postprocess import *
|
||||||
from pyassimp.helper import *
|
from pyassimp.helper import *
|
||||||
|
|
||||||
|
@ -289,8 +291,13 @@ class PyAssimp3DViewer:
|
||||||
|
|
||||||
stride = 24 # 6 * 4 bytes
|
stride = 24 # 6 * 4 bytes
|
||||||
|
|
||||||
glUniform4f( shader.Material_diffuse, *mesh.material.properties["diffuse"] )
|
diffuse = mesh.material.properties["diffuse"]
|
||||||
glUniform4f( shader.Material_ambient, *mesh.material.properties["ambient"] )
|
if len(diffuse) == 3: diffuse.append(1.0)
|
||||||
|
ambient = mesh.material.properties["ambient"]
|
||||||
|
if len(ambient) == 3: ambient.append(1.0)
|
||||||
|
|
||||||
|
glUniform4f( shader.Material_diffuse, *diffuse )
|
||||||
|
glUniform4f( shader.Material_ambient, *ambient )
|
||||||
|
|
||||||
vbo = mesh.gl["vbo"]
|
vbo = mesh.gl["vbo"]
|
||||||
vbo.bind()
|
vbo.bind()
|
||||||
|
@ -403,8 +410,6 @@ if __name__ == '__main__':
|
||||||
app.render()
|
app.render()
|
||||||
app.controls_3d(0)
|
app.controls_3d(0)
|
||||||
if pygame.K_f in app.keys: pygame.display.toggle_fullscreen()
|
if pygame.K_f in app.keys: pygame.display.toggle_fullscreen()
|
||||||
if pygame.K_s in app.keys: app.screenshot()
|
|
||||||
if pygame.K_v in app.keys: app.check_visibility()
|
|
||||||
if pygame.K_TAB in app.keys: app.cycle_cameras()
|
if pygame.K_TAB in app.keys: app.cycle_cameras()
|
||||||
if pygame.K_ESCAPE in app.keys:
|
if pygame.K_ESCAPE in app.keys:
|
||||||
break
|
break
|
|
@ -0,0 +1,13 @@
|
||||||
|
pyassimp examples
|
||||||
|
=================
|
||||||
|
|
||||||
|
- `sample.py`: shows how to load a model with pyassimp, and display some statistics.
|
||||||
|
- `3d_viewer.py`: an OpenGL 3D viewer that requires shaders
|
||||||
|
- `fixed_pipeline_3d_viewer`: an OpenGL 3D viewer using the old fixed-pipeline.
|
||||||
|
Only for illustration example. Base new projects on `3d_viewer.py`.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements for the 3D viewers:
|
||||||
|
|
||||||
|
- `pyopengl` (on Ubuntu/Debian, `sudo apt-get install python-opengl`)
|
||||||
|
- `pygame` (on Ubuntu/Debian, `sudo apt-get install python-pygame`)
|
|
@ -35,7 +35,7 @@ logging.basicConfig(level=logging.INFO)
|
||||||
import math
|
import math
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
from pyassimp import core as pyassimp
|
import pyassimp
|
||||||
from pyassimp.postprocess import *
|
from pyassimp.postprocess import *
|
||||||
from pyassimp.helper import *
|
from pyassimp.helper import *
|
||||||
|
|
||||||
|
@ -204,7 +204,6 @@ class GLRenderer():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not hasattr(mat, "gl_mat"): # evaluate once the mat properties, and cache the values in a glDisplayList.
|
if not hasattr(mat, "gl_mat"): # evaluate once the mat properties, and cache the values in a glDisplayList.
|
||||||
|
|
||||||
diffuse = numpy.array(mat.properties.get("diffuse", [0.8, 0.8, 0.8, 1.0]))
|
diffuse = numpy.array(mat.properties.get("diffuse", [0.8, 0.8, 0.8, 1.0]))
|
||||||
specular = numpy.array(mat.properties.get("specular", [0., 0., 0., 1.0]))
|
specular = numpy.array(mat.properties.get("specular", [0., 0., 0., 1.0]))
|
||||||
ambient = numpy.array(mat.properties.get("ambient", [0.2, 0.2, 0.2, 1.0]))
|
ambient = numpy.array(mat.properties.get("ambient", [0.2, 0.2, 0.2, 1.0]))
|
||||||
|
@ -234,14 +233,6 @@ class GLRenderer():
|
||||||
|
|
||||||
gl_time = glutGet(GLUT_ELAPSED_TIME)
|
gl_time = glutGet(GLUT_ELAPSED_TIME)
|
||||||
|
|
||||||
# Compute the new position of the camera and set it
|
|
||||||
self.x += self.dp * self.lx * 0.01 * (gl_time-self.prev_time)
|
|
||||||
self.z += self.dp * self.lz * 0.01 * (gl_time-self.prev_time)
|
|
||||||
self.angle += self.drot * 0.1 * (gl_time-self.prev_time)
|
|
||||||
self.lx = math.sin(self.angle)
|
|
||||||
self.lz = -math.cos(self.angle)
|
|
||||||
self.set_default_camera()
|
|
||||||
|
|
||||||
self.angle = (gl_time - self.prev_time) * 0.1
|
self.angle = (gl_time - self.prev_time) * 0.1
|
||||||
|
|
||||||
self.prev_time = gl_time
|
self.prev_time = gl_time
|
|
@ -12,29 +12,32 @@ loading and querying of 3d models using pyassimp works.
|
||||||
|
|
||||||
import sys,os
|
import sys,os
|
||||||
import sample
|
import sample
|
||||||
from pyassimp import pyassimp,errors
|
from pyassimp import errors
|
||||||
|
|
||||||
# paths to be walkd recursively
|
# paths to be walkd recursively
|
||||||
basepaths = [os.path.join('..','..','test','models'), os.path.join('..','..','test','models-nonbsd')]
|
basepaths = [os.path.join('..','..','..','test','models'), os.path.join('..','..','..','test','models-nonbsd')]
|
||||||
|
|
||||||
# file extensions to be considered
|
# file extensions to be considered
|
||||||
extensions = ['.3ds','.x','.lwo','.obj','.md5mesh','.dxf','.ply','.stl','.dae','.md5anim','.lws','.irrmesh','.nff','.off','.blend']
|
extensions = ['.3ds','.x','.lwo','.obj','.md5mesh','.dxf','.ply','.stl','.dae','.md5anim','.lws','.irrmesh','.nff','.off','.blend']
|
||||||
|
|
||||||
def run_tests():
|
def run_tests():
|
||||||
ok,err = 0,0
|
ok,err = 0,0
|
||||||
for path in basepaths:
|
for path in basepaths:
|
||||||
for root, dirs, files in os.walk(path):
|
print("Looking for models in %s..." % path)
|
||||||
for afile in files:
|
for root, dirs, files in os.walk(path):
|
||||||
base,ext = os.path.splitext(afile)
|
for afile in files:
|
||||||
if ext in extensions:
|
base,ext = os.path.splitext(afile)
|
||||||
try:
|
if ext in extensions:
|
||||||
sample.main(os.path.join(root,afile))
|
try:
|
||||||
ok += 1
|
sample.main(os.path.join(root,afile))
|
||||||
except errors.AssimpError as error:
|
ok += 1
|
||||||
# assimp error is fine, this is a controlled case
|
except errors.AssimpError as error:
|
||||||
print error
|
# assimp error is fine, this is a controlled case
|
||||||
err += 1
|
print error
|
||||||
print '** Loaded %s models, got controlled errors for %s files' % (ok,err)
|
err += 1
|
||||||
|
except Exception:
|
||||||
|
print("Error encountered while loading <%s>"%os.path.join(root,afile))
|
||||||
|
print('** Loaded %s models, got controlled errors for %s files' % (ok,err))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -7,9 +7,10 @@ This module demonstrates the functionality of PyAssimp.
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
from pyassimp import core as pyassimp
|
import pyassimp
|
||||||
|
import pyassimp.postprocess
|
||||||
|
|
||||||
def recur_node(node,level = 0):
|
def recur_node(node,level = 0):
|
||||||
print(" " + "\t" * level + "- " + str(node))
|
print(" " + "\t" * level + "- " + str(node))
|
||||||
|
@ -19,7 +20,7 @@ def recur_node(node,level = 0):
|
||||||
|
|
||||||
def main(filename=None):
|
def main(filename=None):
|
||||||
|
|
||||||
scene = pyassimp.load(filename)
|
scene = pyassimp.load(filename, pyassimp.postprocess.aiProcess_Triangulate)
|
||||||
|
|
||||||
#the model we load
|
#the model we load
|
||||||
print("MODEL:" + filename)
|
print("MODEL:" + filename)
|
||||||
|
@ -48,7 +49,7 @@ def main(filename=None):
|
||||||
print(" no normals")
|
print(" no normals")
|
||||||
print(" colors:" + str(len(mesh.colors)))
|
print(" colors:" + str(len(mesh.colors)))
|
||||||
tcs = mesh.texturecoords
|
tcs = mesh.texturecoords
|
||||||
if tcs:
|
if tcs.any():
|
||||||
for index, tc in enumerate(tcs):
|
for index, tc in enumerate(tcs):
|
||||||
print(" texture-coords "+ str(index) + ":" + str(len(tcs[index])) + "first3:" + str(tcs[index][:3]))
|
print(" texture-coords "+ str(index) + ":" + str(len(tcs[index])) + "first3:" + str(tcs[index][:3]))
|
||||||
|
|
||||||
|
@ -77,5 +78,12 @@ def main(filename=None):
|
||||||
# Finally release the model
|
# Finally release the model
|
||||||
pyassimp.release(scene)
|
pyassimp.release(scene)
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("Usage: sample.py <3d model>")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(sys.argv[1] if len(sys.argv)>1 else None)
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
usage()
|
||||||
|
else:
|
||||||
|
main(sys.argv[1])
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue