Merge remote-tracking branch 'origin'
Conflicts: code/C4DImporter.cpp code/OgreImporter.hpull/536/head
commit
8c45a4dc3b
|
@ -10,7 +10,7 @@ build
|
||||||
# Output
|
# Output
|
||||||
bin/
|
bin/
|
||||||
lib/
|
lib/
|
||||||
contrib/
|
|
||||||
|
|
||||||
# Generated
|
# Generated
|
||||||
assimp.pc
|
assimp.pc
|
||||||
|
@ -54,3 +54,7 @@ tools/assimp_view/assimp_viewer.vcxproj.user
|
||||||
|
|
||||||
# Unix editor backups
|
# Unix editor backups
|
||||||
*~
|
*~
|
||||||
|
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
|
||||||
|
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
|
||||||
|
Assimp.opensdf
|
||||||
|
contrib/zlib/CTestTestfile.cmake
|
||||||
|
|
51
.travis.yml
51
.travis.yml
|
@ -1,16 +1,22 @@
|
||||||
before_install:
|
before_install:
|
||||||
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install cmake python3
|
- sudo apt-get install cmake python3
|
||||||
|
- if [ $LINUX ]; then sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; fi
|
||||||
|
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
global:
|
||||||
|
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||||
|
matrix:
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=YES
|
- LINUX=1 TRAVIS_NO_EXPORT=YES
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=NO
|
- LINUX=1 TRAVIS_NO_EXPORT=NO
|
||||||
- LINUX=1 TRAVIS_STATIC_BUILD=ON
|
- LINUX=1 SHARED_BUILD=ON
|
||||||
- LINUX=1 TRAVIS_STATIC_BUILD=OFF
|
- LINUX=1 SHARED_BUILD=OFF
|
||||||
- WINDOWS=1 TRAVIS_NO_EXPORT=YES
|
- ANDROID=1
|
||||||
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
|
|
||||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=ON
|
|
||||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
|
|
||||||
|
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
|
@ -19,19 +25,22 @@ compiler:
|
||||||
- clang
|
- clang
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ $WINDOWS ]; then travis_retry sudo apt-get install -q -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64; fi
|
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
|
- if [ $ANDROID ]; then
|
||||||
- make
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ;
|
||||||
- sudo make install
|
else
|
||||||
- sudo ldconfig
|
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD ;
|
||||||
- cd test/unit
|
make ;
|
||||||
- ../../bin/unit
|
sudo make install ;
|
||||||
- cd ../regression
|
sudo ldconfig ;
|
||||||
- chmod 755 run.py
|
cd test/unit ;
|
||||||
- ./run.py
|
../../bin/unit ;
|
||||||
- echo "=========================================================="
|
cd ../regression ;
|
||||||
- echo "REGRESSION TEST FAILS (results/run_regression_suite_failures.csv)"
|
chmod 755 run.py ;
|
||||||
- cat ../results/run_regression_suite_failures.csv
|
./run.py ;
|
||||||
|
echo "==========================================================" ;
|
||||||
|
echo "REGRESSION TEST FAILURES (results/run_regression_suite_failures.csv)" ;
|
||||||
|
cat ../results/run_regression_suite_failures.csv;
|
||||||
|
fi
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
cmake_minimum_required( VERSION 2.8 )
|
cmake_minimum_required( VERSION 2.8 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
|
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
|
||||||
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
|
#set(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||||
|
set(LINK_SEARCH_START_STATIC TRUE)
|
||||||
|
endif(NOT BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
# Define here the needed parameters
|
# Define here the needed parameters
|
||||||
set (ASSIMP_VERSION_MAJOR 3)
|
set (ASSIMP_VERSION_MAJOR 3)
|
||||||
set (ASSIMP_VERSION_MINOR 1)
|
set (ASSIMP_VERSION_MINOR 1)
|
||||||
|
@ -11,6 +17,8 @@ set (PROJECT_VERSION "${ASSIMP_VERSION}")
|
||||||
|
|
||||||
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
||||||
|
|
||||||
|
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||||
|
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git rev-parse --abbrev-ref HEAD
|
COMMAND git rev-parse --abbrev-ref HEAD
|
||||||
|
@ -86,9 +94,6 @@ SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||||
|
|
||||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
||||||
|
|
||||||
# Allow the user to build a shared or static library
|
|
||||||
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
|
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
# add make uninstall capability
|
# add make uninstall capability
|
||||||
|
|
5
CREDITS
5
CREDITS
|
@ -151,3 +151,8 @@ Ogre Binary format support
|
||||||
|
|
||||||
- Filip Wasil, Tieto Poland Sp. z o.o.
|
- Filip Wasil, Tieto Poland Sp. z o.o.
|
||||||
Android JNI asset extraction support
|
Android JNI asset extraction support
|
||||||
|
|
||||||
|
- Richard Steffen
|
||||||
|
Contributed X File exporter
|
||||||
|
Contributed ExportProperties interface
|
||||||
|
|
||||||
|
|
49
Readme.md
49
Readme.md
|
@ -1,18 +1,25 @@
|
||||||
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 shared, in-memory format__. It supports more than __40 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more.
|
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||||
|
|
||||||
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)
|
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
|
|
||||||
[open3mod](https://github.com/acgessler/open3mod) is an Open Source 3D model viewer based off Assimp's import and export abilities.
|
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||||
|
|
||||||
|
This is the development trunk 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 is:
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
||||||
|
|
||||||
|
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
|
|
||||||
The library provides importers for a lot of file formats, including:
|
A full list [is here](http://assimp.sourceforge.net/main_features_formats.html).
|
||||||
|
__Importers__:
|
||||||
|
|
||||||
- 3DS
|
- 3DS
|
||||||
- BLEND (Blender 3D)
|
- BLEND (Blender)
|
||||||
- DAE/Collada
|
- DAE/Collada
|
||||||
- FBX
|
- FBX
|
||||||
- IFC-STEP
|
- IFC-STEP
|
||||||
|
@ -46,13 +53,13 @@ The library provides importers for a lot of file formats, including:
|
||||||
- Ogre Binary
|
- Ogre Binary
|
||||||
- Ogre XML
|
- Ogre XML
|
||||||
- Q3D
|
- Q3D
|
||||||
- ASSBIN (Assimp scene serialization)
|
- ASSBIN (Assimp custom format)
|
||||||
|
|
||||||
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries.
|
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||||
|
|
||||||
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
||||||
|
|
||||||
Exporters include:
|
__Exporters__:
|
||||||
|
|
||||||
- DAE (Collada)
|
- DAE (Collada)
|
||||||
- STL
|
- STL
|
||||||
|
@ -63,23 +70,21 @@ Exporters include:
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
- ASSBIN
|
- ASSBIN
|
||||||
|
|
||||||
See [the full list here](http://assimp.sourceforge.net/main_features_formats.html).
|
### Building ###
|
||||||
|
|
||||||
|
|
||||||
|
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||||
|
|
||||||
|
|
||||||
#### Repository structure ####
|
#### Repository structure ####
|
||||||
|
|
||||||
|
|
||||||
Open Asset Import Library is implemented in C++ (but provides both a C and a
|
Open Asset Import Library is implemented in C++. The directory structure is:
|
||||||
C++ish interface). The directory structure is:
|
|
||||||
|
|
||||||
/bin Folder for binaries, only used on Windows
|
|
||||||
/code Source code
|
/code Source code
|
||||||
/contrib Third-party libraries
|
/contrib Third-party libraries
|
||||||
/doc Documentation (doxysource and pre-compiled docs)
|
/doc Documentation (doxysource and pre-compiled docs)
|
||||||
/include Public header C and C++ header files
|
/include Public header C and C++ header files
|
||||||
/lib Static library location for Windows
|
|
||||||
/obj Object file location for Windows
|
|
||||||
/scripts Scripts used to generate the loading code for some formats
|
/scripts Scripts used to generate the loading code for some formats
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
|
@ -90,24 +95,15 @@ C++ish interface). The directory structure is:
|
||||||
CMake has superseeded all legacy build options!)
|
CMake has superseeded all legacy build options!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Building ###
|
|
||||||
|
|
||||||
|
|
||||||
Take a look into the `INSTALL` file. Our build system is CMake, if you already used CMake before there is a good chance you know what to do.
|
|
||||||
|
|
||||||
|
|
||||||
### Where to get help ###
|
### Where to get help ###
|
||||||
|
|
||||||
|
|
||||||
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
||||||
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
||||||
|
|
||||||
If the documentation doesn't solve your problems,
|
If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
|
||||||
[try our forums at SF.net](http://sourceforge.net/p/assimp/discussion/817654) or ask on
|
|
||||||
[StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
|
||||||
|
|
||||||
For development discussions, there is also a mailing list, _assimp-discussions_
|
For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
|
||||||
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
||||||
|
|
||||||
### Contributing ###
|
### Contributing ###
|
||||||
|
@ -115,10 +111,9 @@ For development discussions, there is also a mailing list, _assimp-discussions_
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
a pull request with your changes against the main repository's `master` branch.
|
a pull request with your changes against the main repository's `master` branch.
|
||||||
|
|
||||||
|
|
||||||
### License ###
|
### License ###
|
||||||
|
|
||||||
Our license is based on the modified, __3-clause BSD__-License, which is very liberal.
|
Our license is based on the modified, __3-clause BSD__-License.
|
||||||
|
|
||||||
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
|
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
|
||||||
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
|
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# this one sets internal to crosscompile (in theory)
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
|
||||||
|
# the minimalistic settings
|
||||||
|
SET(CMAKE_C_COMPILER "/usr/bin/x86_64-w64-mingw32-gcc")
|
||||||
|
SET(CMAKE_CXX_COMPILER "/usr/bin/x86_64-w64-mingw32-g++")
|
||||||
|
SET(CMAKE_RC_COMPILER "/usr/bin/x86_64-w64-mingw32-windres")
|
||||||
|
|
||||||
|
# where is the target (so called staging) environment
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
||||||
|
|
||||||
|
# search for programs in the build host directories (default BOTH)
|
||||||
|
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
@ -147,7 +147,7 @@ namespace {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
||||||
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
||||||
if(!outfile) {
|
if(!outfile) {
|
||||||
|
@ -191,8 +191,8 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
||||||
WriteMeshes();
|
|
||||||
WriteMaterials();
|
WriteMaterials();
|
||||||
|
WriteMeshes();
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
||||||
|
|
|
@ -757,7 +757,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
AssbinExport exporter;
|
AssbinExport exporter;
|
||||||
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
||||||
|
|
|
@ -623,7 +623,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||||
|
|
||||||
} // end of namespace AssxmlExport
|
} // end of namespace AssxmlExport
|
||||||
|
|
||||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
||||||
if (!out) return;
|
if (!out) return;
|
||||||
|
|
|
@ -123,6 +123,16 @@ namespace Blender {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(disable:4351)
|
# pragma warning(disable:4351)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ObjectCompare {
|
||||||
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
|
return strcmp(left->id.name, right->id.name) == -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// When keeping objects in sets, sort them by their name.
|
||||||
|
typedef std::set<const Object*, ObjectCompare> ObjectSet;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** ConversionData acts as intermediate storage location for
|
/** ConversionData acts as intermediate storage location for
|
||||||
* the various ConvertXXX routines in BlenderImporter.*/
|
* the various ConvertXXX routines in BlenderImporter.*/
|
||||||
|
@ -135,7 +145,13 @@ namespace Blender {
|
||||||
, db(db)
|
, db(db)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::set<const Object*> objects;
|
struct ObjectCompare {
|
||||||
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
|
return strcmp(left->id.name, right->id.name) == -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ObjectSet objects;
|
||||||
|
|
||||||
TempArray <std::vector, aiMesh> meshes;
|
TempArray <std::vector, aiMesh> meshes;
|
||||||
TempArray <std::vector, aiCamera> cameras;
|
TempArray <std::vector, aiCamera> cameras;
|
||||||
|
|
|
@ -561,24 +561,26 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
||||||
|
|
||||||
if (index == static_cast<unsigned int>( -1 )) {
|
if (index == static_cast<unsigned int>( -1 )) {
|
||||||
|
// Setup a default material.
|
||||||
// ok, we need to add a dedicated default material for some poor material-less meshes
|
|
||||||
boost::shared_ptr<Material> p(new Material());
|
boost::shared_ptr<Material> p(new Material());
|
||||||
|
ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name)-2);
|
||||||
strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
|
strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
|
||||||
|
|
||||||
|
// Note: MSVC11 does not zero-initialize Material here, although it should.
|
||||||
|
// Thus all relevant fields should be explicitly initialized. We cannot add
|
||||||
|
// a default constructor to Material since the DNA codegen does not support
|
||||||
|
// parsing it.
|
||||||
p->r = p->g = p->b = 0.6f;
|
p->r = p->g = p->b = 0.6f;
|
||||||
p->specr = p->specg = p->specb = 0.6f;
|
p->specr = p->specg = p->specb = 0.6f;
|
||||||
p->ambr = p->ambg = p->ambb = 0.0f;
|
p->ambr = p->ambg = p->ambb = 0.0f;
|
||||||
p->mirr = p->mirg = p->mirb = 0.0f;
|
p->mirr = p->mirg = p->mirb = 0.0f;
|
||||||
p->emit = 0.f;
|
p->emit = 0.f;
|
||||||
p->alpha = 0.f;
|
p->alpha = 0.f;
|
||||||
|
p->har = 0;
|
||||||
// XXX add more / or add default c'tor to Material
|
|
||||||
|
|
||||||
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
||||||
conv_data.materials_raw.push_back(p);
|
conv_data.materials_raw.push_back(p);
|
||||||
|
LogInfo("Adding default material");
|
||||||
LogInfo("Adding default material ...");
|
|
||||||
}
|
}
|
||||||
mesh->mMaterialIndex = index;
|
mesh->mMaterialIndex = index;
|
||||||
}
|
}
|
||||||
|
@ -593,6 +595,7 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
|
|
||||||
aiMaterial* mout = new aiMaterial();
|
aiMaterial* mout = new aiMaterial();
|
||||||
conv_data.materials->push_back(mout);
|
conv_data.materials->push_back(mout);
|
||||||
|
// For any new material field handled here, the default material above must be updated with an appropriate default value.
|
||||||
|
|
||||||
// set material name
|
// set material name
|
||||||
aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
|
aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
|
||||||
|
@ -1046,7 +1049,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
||||||
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
|
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
|
||||||
{
|
{
|
||||||
std::deque<const Object*> children;
|
std::deque<const Object*> children;
|
||||||
for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
|
for(ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
|
||||||
const Object* object = *it;
|
const Object* object = *it;
|
||||||
if (object->parent == obj) {
|
if (object->parent == obj) {
|
||||||
children.push_back(object);
|
children.push_back(object);
|
||||||
|
|
|
@ -129,9 +129,11 @@ public:
|
||||||
{
|
{
|
||||||
case aiOrigin_CUR:
|
case aiOrigin_CUR:
|
||||||
cursor += pOffset;
|
cursor += pOffset;
|
||||||
|
break;
|
||||||
|
|
||||||
case aiOrigin_END:
|
case aiOrigin_END:
|
||||||
cursor = file_size - pOffset;
|
cursor = file_size - pOffset;
|
||||||
|
break;
|
||||||
|
|
||||||
case aiOrigin_SET:
|
case aiOrigin_SET:
|
||||||
cursor = pOffset;
|
cursor = pOffset;
|
||||||
|
|
|
@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file C4DImporter.cpp
|
/** @file C4DImporter.cpp
|
||||||
* @brief Implementation of the Cinema4D importer class.
|
* @brief Implementation of the Cinema4D importer class.
|
||||||
*/
|
*/
|
||||||
|
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
|
|
||||||
// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
|
// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
|
||||||
// where it is turned on in the CMake settings.
|
// where it is turned on in the CMake settings.
|
||||||
|
|
|
@ -266,8 +266,6 @@ SET( LWS_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET( MD2_SRCS
|
SET( MD2_SRCS
|
||||||
MD2FileData.h
|
MD2FileData.h
|
||||||
MD2Loader.cpp
|
MD2Loader.cpp
|
||||||
|
@ -361,6 +359,13 @@ SET( Ogre_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( Ogre FILES ${Ogre_SRCS})
|
SOURCE_GROUP( Ogre FILES ${Ogre_SRCS})
|
||||||
|
|
||||||
|
SET( OpenGEX_SRCS
|
||||||
|
OpenGEXImporter.cpp
|
||||||
|
OpenGEXImporter.h
|
||||||
|
OpenGEXStructs.h
|
||||||
|
)
|
||||||
|
SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS})
|
||||||
|
|
||||||
SET( Ply_SRCS
|
SET( Ply_SRCS
|
||||||
PlyLoader.cpp
|
PlyLoader.cpp
|
||||||
PlyLoader.h
|
PlyLoader.h
|
||||||
|
@ -636,6 +641,17 @@ SET( unzip_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( unzip FILES ${unzip_SRCS})
|
SOURCE_GROUP( unzip FILES ${unzip_SRCS})
|
||||||
|
|
||||||
|
SET ( openddl_parser_SRCS
|
||||||
|
../contrib/openddlparser/code/OpenDDLParser.cpp
|
||||||
|
../contrib/openddlparser/code/DDLNode.cpp
|
||||||
|
../contrib/openddlparser/code/Value.cpp
|
||||||
|
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
|
||||||
|
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
|
||||||
|
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
|
||||||
|
../contrib/openddlparser/include/openddlparser/DDLNode.h
|
||||||
|
../contrib/openddlparser/include/openddlparser/Value.h
|
||||||
|
)
|
||||||
|
SOURCE_GROUP( openddl_parser FILES ${openddl_parser_SRCS})
|
||||||
|
|
||||||
# VC2010 fixes
|
# VC2010 fixes
|
||||||
if(MSVC10)
|
if(MSVC10)
|
||||||
|
@ -691,6 +707,7 @@ SET( assimp_src
|
||||||
${OFFFormat_SRCS}
|
${OFFFormat_SRCS}
|
||||||
${Obj_SRCS}
|
${Obj_SRCS}
|
||||||
${Ogre_SRCS}
|
${Ogre_SRCS}
|
||||||
|
${OpenGEX_SRCS}
|
||||||
${Ply_SRCS}
|
${Ply_SRCS}
|
||||||
${Q3D_SRCS}
|
${Q3D_SRCS}
|
||||||
${Q3BSP_SRCS}
|
${Q3BSP_SRCS}
|
||||||
|
@ -715,6 +732,7 @@ SET( assimp_src
|
||||||
${unzip_compile_SRCS}
|
${unzip_compile_SRCS}
|
||||||
${Poly2Tri_SRCS}
|
${Poly2Tri_SRCS}
|
||||||
${Clipper_SRCS}
|
${Clipper_SRCS}
|
||||||
|
${openddl_parser_SRCS}
|
||||||
# Necessary to show the headers in the project when using the VC++ generator:
|
# Necessary to show the headers in the project when using the VC++ generator:
|
||||||
${Boost_SRCS}
|
${Boost_SRCS}
|
||||||
|
|
||||||
|
@ -722,6 +740,11 @@ SET( assimp_src
|
||||||
${COMPILER_HEADERS}
|
${COMPILER_HEADERS}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
../contrib/openddlparser/include
|
||||||
|
)
|
||||||
|
|
||||||
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
SET( assimp_src ${assimp_src} ${C4D_SRCS})
|
SET( assimp_src ${assimp_src} ${C4D_SRCS})
|
||||||
|
@ -730,7 +753,7 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
|
||||||
ADD_LIBRARY( assimp ${assimp_src} )
|
ADD_LIBRARY( assimp ${assimp_src} )
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
|
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} )
|
||||||
|
|
||||||
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||||
set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
|
set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
|
||||||
|
|
|
@ -154,13 +154,17 @@ void COBImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
|
DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
|
||||||
void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
|
|
||||||
if (head[16]!='L') {
|
if (head[16]!='L') {
|
||||||
ThrowException("File is big-endian, which is not supported");
|
ThrowException("File is big-endian, which is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// load data into intermediate structures
|
// load data into intermediate structures
|
||||||
(this->*load)(scene,stream.get());
|
if (head[15]=='A') {
|
||||||
|
ReadAsciiFile(scene, stream.get());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReadBinaryFile(scene, stream.get());
|
||||||
|
}
|
||||||
if(scene.nodes.empty()) {
|
if(scene.nodes.empty()) {
|
||||||
ThrowException("No nodes loaded");
|
ThrowException("No nodes loaded");
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Assimp
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
std::string path = "";
|
std::string path = "";
|
||||||
std::string file = pFile;
|
std::string file = pFile;
|
||||||
|
|
|
@ -405,6 +405,7 @@ struct Controller
|
||||||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
/** A collada material. Pretty much the only member is a reference to an effect. */
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
|
std::string mName;
|
||||||
std::string mEffect;
|
std::string mEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, -1, 0, 0,
|
0, -1, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
// store all meshes
|
// store all meshes
|
||||||
StoreSceneMeshes( pScene);
|
StoreSceneMeshes( pScene);
|
||||||
|
|
||||||
|
@ -1385,7 +1385,7 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
|
||||||
|
|
||||||
// create material
|
// create material
|
||||||
aiMaterial* mat = new aiMaterial;
|
aiMaterial* mat = new aiMaterial;
|
||||||
aiString name( matIt->first);
|
aiString name( material.mName.empty() ? matIt->first : material.mName );
|
||||||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||||
|
|
||||||
// store the material
|
// store the material
|
||||||
|
|
|
@ -66,7 +66,7 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
||||||
{
|
{
|
||||||
mRootNode = NULL;
|
mRootNode = NULL;
|
||||||
mUnitSize = 1.0f;
|
mUnitSize = 1.0f;
|
||||||
mUpDirection = UP_Z;
|
mUpDirection = UP_Y;
|
||||||
|
|
||||||
// We assume the newest file format by default
|
// We assume the newest file format by default
|
||||||
mFormat = FV_1_5_n;
|
mFormat = FV_1_5_n;
|
||||||
|
@ -231,10 +231,10 @@ void ColladaParser::ReadAssetInfo()
|
||||||
const char* content = GetTextContent();
|
const char* content = GetTextContent();
|
||||||
if( strncmp( content, "X_UP", 4) == 0)
|
if( strncmp( content, "X_UP", 4) == 0)
|
||||||
mUpDirection = UP_X;
|
mUpDirection = UP_X;
|
||||||
else if( strncmp( content, "Y_UP", 4) == 0)
|
else if( strncmp( content, "Z_UP", 4) == 0)
|
||||||
mUpDirection = UP_Y;
|
|
||||||
else
|
|
||||||
mUpDirection = UP_Z;
|
mUpDirection = UP_Z;
|
||||||
|
else
|
||||||
|
mUpDirection = UP_Y;
|
||||||
|
|
||||||
// check element end
|
// check element end
|
||||||
TestClosing( "up_axis");
|
TestClosing( "up_axis");
|
||||||
|
@ -823,6 +823,7 @@ void ColladaParser::ReadMaterialLibrary()
|
||||||
if( mReader->isEmptyElement())
|
if( mReader->isEmptyElement())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::map<std::string, int> names;
|
||||||
while( mReader->read())
|
while( mReader->read())
|
||||||
{
|
{
|
||||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
@ -833,8 +834,32 @@ void ColladaParser::ReadMaterialLibrary()
|
||||||
int attrID = GetAttribute( "id");
|
int attrID = GetAttribute( "id");
|
||||||
std::string id = mReader->getAttributeValue( attrID);
|
std::string id = mReader->getAttributeValue( attrID);
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
int attrName = TestAttribute("name");
|
||||||
|
if (attrName >= 0)
|
||||||
|
name = mReader->getAttributeValue( attrName);
|
||||||
|
|
||||||
// create an entry and store it in the library under its ID
|
// create an entry and store it in the library under its ID
|
||||||
ReadMaterial(mMaterialLibrary[id] = Material());
|
mMaterialLibrary[id] = Material();
|
||||||
|
|
||||||
|
if( !name.empty())
|
||||||
|
{
|
||||||
|
std::map<std::string, int>::iterator it = names.find( name);
|
||||||
|
if( it != names.end())
|
||||||
|
{
|
||||||
|
std::ostringstream strStream;
|
||||||
|
strStream << ++it->second;
|
||||||
|
name.append( " " + strStream.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
names[name] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMaterialLibrary[id].mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadMaterial( mMaterialLibrary[id]);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// ignore the rest
|
// ignore the rest
|
||||||
|
@ -1391,6 +1416,9 @@ void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
|
||||||
if( attrTex >= 0 )
|
if( attrTex >= 0 )
|
||||||
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
|
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
|
||||||
//SkipElement();
|
//SkipElement();
|
||||||
|
|
||||||
|
// as we've read texture, the color needs to be 1,1,1,1
|
||||||
|
pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
|
||||||
}
|
}
|
||||||
else if( IsElement( "technique"))
|
else if( IsElement( "technique"))
|
||||||
{
|
{
|
||||||
|
@ -1942,6 +1970,10 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||||
// now here the actual fun starts - these are the indices to construct the mesh data from
|
// now here the actual fun starts - these are the indices to construct the mesh data from
|
||||||
actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
|
actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (IsElement("extra"))
|
||||||
|
{
|
||||||
|
SkipElement("extra");
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName));
|
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName));
|
||||||
|
@ -1956,9 +1988,11 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// small sanity check
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
if (primType != Prim_TriFans && primType != Prim_TriStrips)
|
if (primType != Prim_TriFans && primType != Prim_TriStrips) {
|
||||||
ai_assert(actualPrimitives == numPrimitives);
|
ai_assert(actualPrimitives == numPrimitives);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
|
// only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
|
||||||
subgroup.mNumFaces = actualPrimitives;
|
subgroup.mNumFaces = actualPrimitives;
|
||||||
|
|
|
@ -78,16 +78,16 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
|
// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
|
||||||
// do not use const, because some exporter need to convert the scene temporary
|
// do not use const, because some exporter need to convert the scene temporary
|
||||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneXFile(const char*,IOSystem*, const aiScene*);
|
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*);
|
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
|
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
|
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
|
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// global array of all export formats which Assimp supports in its current build
|
// global array of all export formats which Assimp supports in its current build
|
||||||
|
@ -97,7 +97,7 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
||||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
||||||
#endif
|
#endif
|
||||||
|
@ -232,7 +232,7 @@ bool Exporter :: IsDefaultIOHandler() const
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int )
|
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
if (pimpl->blob) {
|
if (pimpl->blob) {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
|
@ -288,7 +288,7 @@ bool IsVerboseFormat(const aiScene* pScene)
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
|
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
// format. They will likely not be aware that there is a flag in the scene to indicate
|
// format. They will likely not be aware that there is a flag in the scene to indicate
|
||||||
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
||||||
// meshes upfront.
|
// meshes upfront.
|
||||||
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
||||||
|
|
||||||
pimpl->mError = "";
|
pimpl->mError = "";
|
||||||
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
||||||
|
@ -403,7 +403,8 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||||
proc.Execute(scenecopy.get());
|
proc.Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
|
||||||
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
|
||||||
}
|
}
|
||||||
catch (DeadlyExportError& err) {
|
catch (DeadlyExportError& err) {
|
||||||
pimpl->mError = err.what();
|
pimpl->mError = err.what();
|
||||||
|
@ -498,4 +499,116 @@ void Exporter :: UnregisterExporter(const char* id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExportProperties :: ExportProperties() {}
|
||||||
|
|
||||||
|
ExportProperties::ExportProperties(const ExportProperties &other)
|
||||||
|
: mIntProperties(other.mIntProperties),
|
||||||
|
mFloatProperties(other.mFloatProperties),
|
||||||
|
mStringProperties(other.mStringProperties),
|
||||||
|
mMatrixProperties(other.mMatrixProperties)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Set a configuration property
|
||||||
|
void ExportProperties :: SetPropertyInteger(const char* szName, int iValue,
|
||||||
|
bool* bWasExisting /*= NULL*/)
|
||||||
|
{
|
||||||
|
SetGenericProperty<int>(mIntProperties, szName,iValue,bWasExisting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Set a configuration property
|
||||||
|
void ExportProperties :: SetPropertyFloat(const char* szName, float iValue,
|
||||||
|
bool* bWasExisting /*= NULL*/)
|
||||||
|
{
|
||||||
|
SetGenericProperty<float>(mFloatProperties, szName,iValue,bWasExisting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Set a configuration property
|
||||||
|
void ExportProperties :: SetPropertyString(const char* szName, const std::string& value,
|
||||||
|
bool* bWasExisting /*= NULL*/)
|
||||||
|
{
|
||||||
|
SetGenericProperty<std::string>(mStringProperties, szName,value,bWasExisting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Set a configuration property
|
||||||
|
void ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value,
|
||||||
|
bool* bWasExisting /*= NULL*/)
|
||||||
|
{
|
||||||
|
SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value,bWasExisting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Get a configuration property
|
||||||
|
int ExportProperties :: GetPropertyInteger(const char* szName,
|
||||||
|
int iErrorReturn /*= 0xffffffff*/) const
|
||||||
|
{
|
||||||
|
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Get a configuration property
|
||||||
|
float ExportProperties :: GetPropertyFloat(const char* szName,
|
||||||
|
float iErrorReturn /*= 10e10*/) const
|
||||||
|
{
|
||||||
|
return GetGenericProperty<float>(mFloatProperties,szName,iErrorReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Get a configuration property
|
||||||
|
const std::string ExportProperties :: GetPropertyString(const char* szName,
|
||||||
|
const std::string& iErrorReturn /*= ""*/) const
|
||||||
|
{
|
||||||
|
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
|
||||||
|
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
|
||||||
|
{
|
||||||
|
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
bool ExportProperties :: HasPropertyInteger(const char* szName) const
|
||||||
|
{
|
||||||
|
return HasGenericProperty<int>(mIntProperties, szName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
bool ExportProperties :: HasPropertyBool(const char* szName) const
|
||||||
|
{
|
||||||
|
return HasGenericProperty<int>(mIntProperties, szName);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
bool ExportProperties :: HasPropertyFloat(const char* szName) const
|
||||||
|
{
|
||||||
|
return HasGenericProperty<float>(mFloatProperties, szName);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
bool ExportProperties :: HasPropertyString(const char* szName) const
|
||||||
|
{
|
||||||
|
return HasGenericProperty<std::string>(mStringProperties, szName);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Has a configuration property
|
||||||
|
bool ExportProperties :: HasPropertyMatrix(const char* szName) const
|
||||||
|
{
|
||||||
|
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // !ASSIMP_BUILD_NO_EXPORT
|
#endif // !ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
|
@ -1971,9 +1971,12 @@ private:
|
||||||
|
|
||||||
// strip AnimationStack:: prefix
|
// strip AnimationStack:: prefix
|
||||||
std::string name = st.Name();
|
std::string name = st.Name();
|
||||||
if(name.substr(0,16) == "AnimationStack::") {
|
if (name.substr(0, 16) == "AnimationStack::") {
|
||||||
name = name.substr(16);
|
name = name.substr(16);
|
||||||
}
|
}
|
||||||
|
else if (name.substr(0, 11) == "AnimStack::") {
|
||||||
|
name = name.substr(11);
|
||||||
|
}
|
||||||
|
|
||||||
anim->mName.Set(name);
|
anim->mName.Set(name);
|
||||||
|
|
||||||
|
@ -2017,12 +2020,18 @@ private:
|
||||||
double min_time = 1e10;
|
double min_time = 1e10;
|
||||||
double max_time = -1e10;
|
double max_time = -1e10;
|
||||||
|
|
||||||
|
int64_t start_time = st.LocalStart();
|
||||||
|
int64_t stop_time = st.LocalStop();
|
||||||
|
double start_timeF = CONVERT_FBX_TIME(start_time);
|
||||||
|
double stop_timeF = CONVERT_FBX_TIME(stop_time);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
|
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
|
||||||
GenerateNodeAnimations(node_anims,
|
GenerateNodeAnimations(node_anims,
|
||||||
kv.first,
|
kv.first,
|
||||||
kv.second,
|
kv.second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start_time, stop_time,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
}
|
}
|
||||||
|
@ -2046,9 +2055,27 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//adjust relative timing for animation
|
||||||
|
{
|
||||||
|
double start_fps = start_timeF * anim_fps;
|
||||||
|
|
||||||
|
for (unsigned int c = 0; c < anim->mNumChannels; c++)
|
||||||
|
{
|
||||||
|
aiNodeAnim* channel = anim->mChannels[c];
|
||||||
|
for (uint32_t i = 0; i < channel->mNumPositionKeys; i++)
|
||||||
|
channel->mPositionKeys[i].mTime -= start_fps;
|
||||||
|
for (uint32_t i = 0; i < channel->mNumRotationKeys; i++)
|
||||||
|
channel->mRotationKeys[i].mTime -= start_fps;
|
||||||
|
for (uint32_t i = 0; i < channel->mNumScalingKeys; i++)
|
||||||
|
channel->mScalingKeys[i].mTime -= start_fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_time -= min_time;
|
||||||
|
}
|
||||||
|
|
||||||
// for some mysterious reason, mDuration is simply the maximum key -- the
|
// for some mysterious reason, mDuration is simply the maximum key -- the
|
||||||
// validator always assumes animations to start at zero.
|
// validator always assumes animations to start at zero.
|
||||||
anim->mDuration = max_time /*- min_time */;
|
anim->mDuration = (stop_timeF - start_timeF) * anim_fps;
|
||||||
anim->mTicksPerSecond = anim_fps;
|
anim->mTicksPerSecond = anim_fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,6 +2085,7 @@ private:
|
||||||
const std::string& fixed_name,
|
const std::string& fixed_name,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time)
|
double& min_time)
|
||||||
{
|
{
|
||||||
|
@ -2150,13 +2178,19 @@ private:
|
||||||
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||||
node_property_map.end(),
|
node_property_map.end(),
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time,
|
||||||
true // input is TRS order, assimp is SRT
|
true // input is TRS order, assimp is SRT
|
||||||
);
|
);
|
||||||
|
|
||||||
ai_assert(nd);
|
ai_assert(nd);
|
||||||
node_anims.push_back(nd);
|
if (nd->mNumPositionKeys == 0 && nd->mNumRotationKeys == 0 && nd->mNumScalingKeys == 0) {
|
||||||
|
delete nd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node_anims.push_back(nd);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2188,6 +2222,7 @@ private:
|
||||||
target,
|
target,
|
||||||
(*chain[i]).second,
|
(*chain[i]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
|
|
||||||
|
@ -2203,6 +2238,7 @@ private:
|
||||||
target,
|
target,
|
||||||
(*chain[i]).second,
|
(*chain[i]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
|
|
||||||
|
@ -2215,12 +2251,18 @@ private:
|
||||||
target,
|
target,
|
||||||
(*chain[i]).second,
|
(*chain[i]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
ai_assert(inv);
|
ai_assert(inv);
|
||||||
node_anims.push_back(inv);
|
if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
|
||||||
|
delete inv;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node_anims.push_back(inv);
|
||||||
|
}
|
||||||
|
|
||||||
ai_assert(TransformationComp_RotationPivotInverse > i);
|
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||||
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||||
|
@ -2233,12 +2275,18 @@ private:
|
||||||
target,
|
target,
|
||||||
(*chain[i]).second,
|
(*chain[i]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
ai_assert(inv);
|
ai_assert(inv);
|
||||||
node_anims.push_back(inv);
|
if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
|
||||||
|
delete inv;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node_anims.push_back(inv);
|
||||||
|
}
|
||||||
|
|
||||||
ai_assert(TransformationComp_RotationPivotInverse > i);
|
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||||
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||||
|
@ -2252,6 +2300,7 @@ private:
|
||||||
target,
|
target,
|
||||||
(*chain[i]).second,
|
(*chain[i]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
|
|
||||||
|
@ -2262,7 +2311,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert(na);
|
ai_assert(na);
|
||||||
node_anims.push_back(na);
|
if (na->mNumPositionKeys == 0 && na->mNumRotationKeys == 0 && na->mNumScalingKeys == 0) {
|
||||||
|
delete na;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node_anims.push_back(na);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2323,13 +2377,14 @@ private:
|
||||||
const Model& target,
|
const Model& target,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time)
|
double& min_time)
|
||||||
{
|
{
|
||||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||||
na->mNodeName.Set(name);
|
na->mNodeName.Set(name);
|
||||||
|
|
||||||
ConvertRotationKeys(na, curves, layer_map, max_time,min_time, target.RotationOrder());
|
ConvertRotationKeys(na, curves, layer_map, start, stop, max_time, min_time, target.RotationOrder());
|
||||||
|
|
||||||
// dummy scaling key
|
// dummy scaling key
|
||||||
na->mScalingKeys = new aiVectorKey[1];
|
na->mScalingKeys = new aiVectorKey[1];
|
||||||
|
@ -2354,13 +2409,14 @@ private:
|
||||||
const Model& /*target*/,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time)
|
double& min_time)
|
||||||
{
|
{
|
||||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||||
na->mNodeName.Set(name);
|
na->mNodeName.Set(name);
|
||||||
|
|
||||||
ConvertScaleKeys(na, curves, layer_map, max_time,min_time);
|
ConvertScaleKeys(na, curves, layer_map, start, stop, max_time, min_time);
|
||||||
|
|
||||||
// dummy rotation key
|
// dummy rotation key
|
||||||
na->mRotationKeys = new aiQuatKey[1];
|
na->mRotationKeys = new aiQuatKey[1];
|
||||||
|
@ -2385,6 +2441,7 @@ private:
|
||||||
const Model& /*target*/,
|
const Model& /*target*/,
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time,
|
double& min_time,
|
||||||
bool inverse = false)
|
bool inverse = false)
|
||||||
|
@ -2392,7 +2449,7 @@ private:
|
||||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||||
na->mNodeName.Set(name);
|
na->mNodeName.Set(name);
|
||||||
|
|
||||||
ConvertTranslationKeys(na, curves, layer_map, max_time,min_time);
|
ConvertTranslationKeys(na, curves, layer_map, start, stop, max_time, min_time);
|
||||||
|
|
||||||
if (inverse) {
|
if (inverse) {
|
||||||
for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) {
|
for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) {
|
||||||
|
@ -2425,6 +2482,7 @@ private:
|
||||||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iter_end,
|
||||||
const LayerMap& layer_map,
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& max_time,
|
||||||
double& min_time,
|
double& min_time,
|
||||||
bool reverse_order = false)
|
bool reverse_order = false)
|
||||||
|
@ -2446,21 +2504,21 @@ private:
|
||||||
KeyFrameListList rotation;
|
KeyFrameListList rotation;
|
||||||
|
|
||||||
if(chain[TransformationComp_Scaling] != iter_end) {
|
if(chain[TransformationComp_Scaling] != iter_end) {
|
||||||
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second);
|
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
|
def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chain[TransformationComp_Translation] != iter_end) {
|
if(chain[TransformationComp_Translation] != iter_end) {
|
||||||
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second);
|
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
|
def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chain[TransformationComp_Rotation] != iter_end) {
|
if(chain[TransformationComp_Rotation] != iter_end) {
|
||||||
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second);
|
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
|
def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
|
||||||
|
@ -2478,17 +2536,20 @@ private:
|
||||||
aiVectorKey* out_scale = new aiVectorKey[times.size()];
|
aiVectorKey* out_scale = new aiVectorKey[times.size()];
|
||||||
aiVectorKey* out_translation = new aiVectorKey[times.size()];
|
aiVectorKey* out_translation = new aiVectorKey[times.size()];
|
||||||
|
|
||||||
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
|
if (times.size())
|
||||||
scaling,
|
{
|
||||||
translation,
|
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
|
||||||
rotation,
|
scaling,
|
||||||
times,
|
translation,
|
||||||
max_time,
|
rotation,
|
||||||
min_time,
|
times,
|
||||||
target.RotationOrder(),
|
max_time,
|
||||||
def_scale,
|
min_time,
|
||||||
def_translate,
|
target.RotationOrder(),
|
||||||
def_rot);
|
def_scale,
|
||||||
|
def_translate,
|
||||||
|
def_rot);
|
||||||
|
}
|
||||||
|
|
||||||
// XXX remove duplicates / redundant keys which this operation did
|
// XXX remove duplicates / redundant keys which this operation did
|
||||||
// likely produce if not all three channels were equally dense.
|
// likely produce if not all three channels were equally dense.
|
||||||
|
@ -2510,6 +2571,7 @@ private:
|
||||||
if(chain[TransformationComp_Scaling] != iter_end) {
|
if(chain[TransformationComp_Scaling] != iter_end) {
|
||||||
ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second,
|
ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
}
|
}
|
||||||
|
@ -2525,6 +2587,7 @@ private:
|
||||||
if(chain[TransformationComp_Rotation] != iter_end) {
|
if(chain[TransformationComp_Rotation] != iter_end) {
|
||||||
ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second,
|
ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time,
|
||||||
target.RotationOrder());
|
target.RotationOrder());
|
||||||
|
@ -2542,6 +2605,7 @@ private:
|
||||||
if(chain[TransformationComp_Translation] != iter_end) {
|
if(chain[TransformationComp_Translation] != iter_end) {
|
||||||
ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second,
|
ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second,
|
||||||
layer_map,
|
layer_map,
|
||||||
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
}
|
}
|
||||||
|
@ -2561,17 +2625,21 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// key (time), value, mapto (component index)
|
// key (time), value, mapto (component index)
|
||||||
typedef boost::tuple< const KeyTimeList*, const KeyValueList*, unsigned int > KeyFrameList;
|
typedef boost::tuple<boost::shared_ptr<KeyTimeList>, boost::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
||||||
typedef std::vector<KeyFrameList> KeyFrameListList;
|
typedef std::vector<KeyFrameList> KeyFrameListList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes)
|
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop)
|
||||||
{
|
{
|
||||||
KeyFrameListList inputs;
|
KeyFrameListList inputs;
|
||||||
inputs.reserve(nodes.size()*3);
|
inputs.reserve(nodes.size()*3);
|
||||||
|
|
||||||
|
//give some breathing room for rounding errors
|
||||||
|
int64_t adj_start = start - 10000;
|
||||||
|
int64_t adj_stop = stop + 10000;
|
||||||
|
|
||||||
BOOST_FOREACH(const AnimationCurveNode* node, nodes) {
|
BOOST_FOREACH(const AnimationCurveNode* node, nodes) {
|
||||||
ai_assert(node);
|
ai_assert(node);
|
||||||
|
|
||||||
|
@ -2596,7 +2664,23 @@ private:
|
||||||
const AnimationCurve* const curve = kv.second;
|
const AnimationCurve* const curve = kv.second;
|
||||||
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
|
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
|
||||||
|
|
||||||
inputs.push_back(boost::make_tuple(&curve->GetKeys(), &curve->GetValues(), mapto));
|
//get values within the start/stop time window
|
||||||
|
boost::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
|
||||||
|
boost::shared_ptr<KeyValueList> Values(new KeyValueList());
|
||||||
|
const int count = curve->GetKeys().size();
|
||||||
|
Keys->reserve(count);
|
||||||
|
Values->reserve(count);
|
||||||
|
for (int n = 0; n < count; n++)
|
||||||
|
{
|
||||||
|
int64_t k = curve->GetKeys().at(n);
|
||||||
|
if (k >= adj_start && k <= adj_stop)
|
||||||
|
{
|
||||||
|
Keys->push_back(k);
|
||||||
|
Values->push_back(curve->GetValues().at(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs.push_back(boost::make_tuple(Keys, Values, mapto));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inputs; // pray for NRVO :-)
|
return inputs; // pray for NRVO :-)
|
||||||
|
@ -2626,7 +2710,7 @@ private:
|
||||||
const size_t count = inputs.size();
|
const size_t count = inputs.size();
|
||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
uint64_t min_tick = std::numeric_limits<uint64_t>::max();
|
int64_t min_tick = std::numeric_limits<int64_t>::max();
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
const KeyFrameList& kfl = inputs[i];
|
const KeyFrameList& kfl = inputs[i];
|
||||||
|
|
||||||
|
@ -2635,7 +2719,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_tick == std::numeric_limits<uint64_t>::max()) {
|
if (min_tick == std::numeric_limits<int64_t>::max()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
keys.push_back(min_tick);
|
keys.push_back(min_tick);
|
||||||
|
@ -2835,6 +2919,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime)
|
double& minTime)
|
||||||
{
|
{
|
||||||
|
@ -2844,36 +2929,40 @@ private:
|
||||||
// layers should be multiplied with each other). There is a FBX
|
// layers should be multiplied with each other). There is a FBX
|
||||||
// property in the layer to specify the behaviour, though.
|
// property in the layer to specify the behaviour, though.
|
||||||
|
|
||||||
const KeyFrameListList& inputs = GetKeyframeList(nodes);
|
const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop);
|
||||||
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
||||||
|
|
||||||
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
||||||
na->mScalingKeys = new aiVectorKey[keys.size()];
|
na->mScalingKeys = new aiVectorKey[keys.size()];
|
||||||
InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
|
if (keys.size() > 0)
|
||||||
|
InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime)
|
double& minTime)
|
||||||
{
|
{
|
||||||
ai_assert(nodes.size());
|
ai_assert(nodes.size());
|
||||||
|
|
||||||
// XXX see notes in ConvertScaleKeys()
|
// XXX see notes in ConvertScaleKeys()
|
||||||
const KeyFrameListList& inputs = GetKeyframeList(nodes);
|
const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop);
|
||||||
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
||||||
|
|
||||||
na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
|
na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
|
||||||
na->mPositionKeys = new aiVectorKey[keys.size()];
|
na->mPositionKeys = new aiVectorKey[keys.size()];
|
||||||
InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
|
if (keys.size() > 0)
|
||||||
|
InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
double& minTime,
|
double& minTime,
|
||||||
Model::RotOrder order)
|
Model::RotOrder order)
|
||||||
|
@ -2881,12 +2970,13 @@ private:
|
||||||
ai_assert(nodes.size());
|
ai_assert(nodes.size());
|
||||||
|
|
||||||
// XXX see notes in ConvertScaleKeys()
|
// XXX see notes in ConvertScaleKeys()
|
||||||
const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes);
|
const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes, start, stop);
|
||||||
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
||||||
|
|
||||||
na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
|
na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
|
||||||
na->mRotationKeys = new aiQuatKey[keys.size()];
|
na->mRotationKeys = new aiQuatKey[keys.size()];
|
||||||
InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
|
if (keys.size() > 0)
|
||||||
|
InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -882,7 +882,7 @@ private:
|
||||||
std::vector<unsigned int> mappings;
|
std::vector<unsigned int> mappings;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<uint64_t> KeyTimeList;
|
typedef std::vector<int64_t> KeyTimeList;
|
||||||
typedef std::vector<float> KeyValueList;
|
typedef std::vector<float> KeyValueList;
|
||||||
|
|
||||||
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
|
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
|
||||||
|
@ -1026,10 +1026,10 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
fbx_simple_property(LocalStart, uint64_t, 0L)
|
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||||
fbx_simple_property(LocalStop, uint64_t, 0L)
|
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||||
fbx_simple_property(ReferenceStart, uint64_t, 0L)
|
fbx_simple_property(ReferenceStart, int64_t, 0L)
|
||||||
fbx_simple_property(ReferenceStop, uint64_t, 0L)
|
fbx_simple_property(ReferenceStop, int64_t, 0L)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -432,6 +432,43 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
|
||||||
|
{
|
||||||
|
err_out = NULL;
|
||||||
|
|
||||||
|
if (t.Type() != TokenType_DATA) {
|
||||||
|
err_out = "expected TOK_DATA token";
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.IsBinary())
|
||||||
|
{
|
||||||
|
const char* data = t.begin();
|
||||||
|
if (data[0] != 'L') {
|
||||||
|
err_out = "failed to parse Int64, unexpected data type";
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
BE_NCONST int64_t id = SafeParse<int64_t>(data + 1, t.end());
|
||||||
|
AI_SWAP8(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: should use size_t here
|
||||||
|
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
||||||
|
ai_assert(length > 0);
|
||||||
|
|
||||||
|
const char* out;
|
||||||
|
const int64_t id = strtol10_64(t.begin(), &out, &length);
|
||||||
|
if (out > t.end()) {
|
||||||
|
err_out = "failed to parse Int64 (text)";
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||||
{
|
{
|
||||||
|
@ -1063,6 +1100,63 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read an array of int64_ts
|
||||||
|
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
const TokenList& tok = el.Tokens();
|
||||||
|
if (tok.empty()) {
|
||||||
|
ParseError("unexpected empty element", &el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok[0]->IsBinary()) {
|
||||||
|
const char* data = tok[0]->begin(), *end = tok[0]->end();
|
||||||
|
|
||||||
|
char type;
|
||||||
|
uint32_t count;
|
||||||
|
ReadBinaryDataArrayHead(data, end, type, count, el);
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != 'l') {
|
||||||
|
ParseError("expected long array (binary)", &el);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> buff;
|
||||||
|
ReadBinaryDataArray(type, count, data, end, buff, el);
|
||||||
|
|
||||||
|
ai_assert(data == end);
|
||||||
|
ai_assert(buff.size() == count * 8);
|
||||||
|
|
||||||
|
out.reserve(count);
|
||||||
|
|
||||||
|
const int64_t* ip = reinterpret_cast<const int64_t*>(&buff[0]);
|
||||||
|
for (unsigned int i = 0; i < count; ++i, ++ip) {
|
||||||
|
BE_NCONST int64_t val = *ip;
|
||||||
|
AI_SWAP8(val);
|
||||||
|
out.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t dim = ParseTokenAsDim(*tok[0]);
|
||||||
|
|
||||||
|
// see notes in ParseVectorDataArray()
|
||||||
|
out.reserve(dim);
|
||||||
|
|
||||||
|
const Scope& scope = GetRequiredScope(el);
|
||||||
|
const Element& a = GetRequiredElement(scope, "a", &el);
|
||||||
|
|
||||||
|
for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) {
|
||||||
|
const int64_t ival = ParseTokenAsInt64(**it++);
|
||||||
|
|
||||||
|
out.push_back(ival);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMatrix4x4 ReadMatrix(const Element& element)
|
aiMatrix4x4 ReadMatrix(const Element& element)
|
||||||
|
@ -1206,6 +1300,18 @@ int ParseTokenAsInt(const Token& t)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// wrapper around ParseTokenAsInt64() with ParseError handling
|
||||||
|
int64_t ParseTokenAsInt64(const Token& t)
|
||||||
|
{
|
||||||
|
const char* err;
|
||||||
|
const int64_t i = ParseTokenAsInt64(t, err);
|
||||||
|
if (err) {
|
||||||
|
ParseError(err, t);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
} // !FBX
|
} // !FBX
|
||||||
} // !Assimp
|
} // !Assimp
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out);
|
||||||
|
|
||||||
float ParseTokenAsFloat(const Token& t, const char*& err_out);
|
float ParseTokenAsFloat(const Token& t, const char*& err_out);
|
||||||
int ParseTokenAsInt(const Token& t, const char*& err_out);
|
int ParseTokenAsInt(const Token& t, const char*& err_out);
|
||||||
|
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out);
|
||||||
std::string ParseTokenAsString(const Token& t, const char*& err_out);
|
std::string ParseTokenAsString(const Token& t, const char*& err_out);
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,6 +216,7 @@ uint64_t ParseTokenAsID(const Token& t);
|
||||||
size_t ParseTokenAsDim(const Token& t);
|
size_t ParseTokenAsDim(const Token& t);
|
||||||
float ParseTokenAsFloat(const Token& t);
|
float ParseTokenAsFloat(const Token& t);
|
||||||
int ParseTokenAsInt(const Token& t);
|
int ParseTokenAsInt(const Token& t);
|
||||||
|
int64_t ParseTokenAsInt64(const Token& t);
|
||||||
std::string ParseTokenAsString(const Token& t);
|
std::string ParseTokenAsString(const Token& t);
|
||||||
|
|
||||||
/* read data arrays */
|
/* read data arrays */
|
||||||
|
@ -225,6 +227,7 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el);
|
||||||
void ParseVectorDataArray(std::vector<float>& out, const Element& el);
|
void ParseVectorDataArray(std::vector<float>& out, const Element& el);
|
||||||
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
||||||
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
|
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
|
||||||
|
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,12 @@ Property* ReadTypedProperty(const Element& element)
|
||||||
else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) {
|
else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) {
|
||||||
return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
|
return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
|
||||||
}
|
}
|
||||||
else if (!strcmp(cs,"ULongLong")) {
|
else if (!strcmp(cs, "ULongLong")) {
|
||||||
return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4]));
|
return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4]));
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cs, "KTime")) {
|
||||||
|
return new TypedProperty<int64_t>(ParseTokenAsInt64(*tok[4]));
|
||||||
|
}
|
||||||
else if (!strcmp(cs,"Vector3D") ||
|
else if (!strcmp(cs,"Vector3D") ||
|
||||||
!strcmp(cs,"ColorRGB") ||
|
!strcmp(cs,"ColorRGB") ||
|
||||||
!strcmp(cs,"Vector") ||
|
!strcmp(cs,"Vector") ||
|
||||||
|
@ -105,7 +108,7 @@ Property* ReadTypedProperty(const Element& element)
|
||||||
ParseTokenAsFloat(*tok[6]))
|
ParseTokenAsFloat(*tok[6]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) {
|
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) {
|
||||||
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
|
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -111,5 +111,18 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
||||||
*bWasExisting = true;
|
*bWasExisting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
template <class T>
|
||||||
|
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||||
|
const char* szName)
|
||||||
|
{
|
||||||
|
ai_assert(NULL != szName);
|
||||||
|
const uint32_t hash = SuperFastHash(szName);
|
||||||
|
|
||||||
|
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
|
||||||
|
if (it == list.end()) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
|
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
|
||||||
|
|
|
@ -648,10 +648,10 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
||||||
ai_assert(InRange(a) && InRange(b));
|
ai_assert(InRange(a) && InRange(b));
|
||||||
|
|
||||||
const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
|
const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
|
||||||
out.verts.reserve( out.verts.size() + cnt );
|
out.verts.reserve( out.verts.size() + cnt + 1);
|
||||||
|
|
||||||
IfcFloat p = a, delta = (b-a)/cnt;
|
IfcFloat p = a, delta = (b-a)/cnt;
|
||||||
for(size_t i = 0; i < cnt; ++i, p += delta) {
|
for(size_t i = 0; i <= cnt; ++i, p += delta) {
|
||||||
out.verts.push_back(Eval(p));
|
out.verts.push_back(Eval(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,43 +523,23 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
|
||||||
// ------------------------------------------------------------------------------------------------
|
void ProcessExtrudedArea(const IfcExtrudedAreaSolid& solid, const TempMesh& curve,
|
||||||
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
|
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
|
||||||
ConversionData& conv, bool collect_openings)
|
|
||||||
{
|
{
|
||||||
TempMesh meshout;
|
// Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
|
||||||
|
// forming new triangles.
|
||||||
// First read the profile description
|
const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.verts.size() > 2;
|
||||||
if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
|
if( solid.Depth < 1e-6 ) {
|
||||||
return;
|
if( has_area ) {
|
||||||
}
|
result.Append(curve);
|
||||||
|
|
||||||
IfcVector3 dir;
|
|
||||||
ConvertDirection(dir,solid.ExtrudedDirection);
|
|
||||||
|
|
||||||
dir *= solid.Depth; /*
|
|
||||||
if(conv.collect_openings && !conv.apply_openings) {
|
|
||||||
dir *= 1000.0;
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Outline: assuming that `meshout.verts` is now a list of vertex points forming
|
|
||||||
// the underlying profile, extrude along the given axis, forming new
|
|
||||||
// triangles.
|
|
||||||
|
|
||||||
std::vector<IfcVector3>& in = meshout.verts;
|
|
||||||
const size_t size=in.size();
|
|
||||||
|
|
||||||
const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
|
|
||||||
if(solid.Depth < 1e-6) {
|
|
||||||
if(has_area) {
|
|
||||||
result = meshout;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.verts.reserve(size*(has_area?4:2));
|
result.verts.reserve(curve.verts.size()*(has_area ? 4 : 2));
|
||||||
result.vertcnt.reserve(meshout.vertcnt.size()+2);
|
result.vertcnt.reserve(curve.verts.size() + 2);
|
||||||
|
std::vector<IfcVector3> in = curve.verts;
|
||||||
|
|
||||||
// First step: transform all vertices into the target coordinate space
|
// First step: transform all vertices into the target coordinate space
|
||||||
IfcMatrix4 trafo;
|
IfcMatrix4 trafo;
|
||||||
|
@ -567,7 +547,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
IfcVector3 vmin, vmax;
|
IfcVector3 vmin, vmax;
|
||||||
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
||||||
BOOST_FOREACH(IfcVector3& v,in) {
|
BOOST_FOREACH(IfcVector3& v, in) {
|
||||||
v *= trafo;
|
v *= trafo;
|
||||||
|
|
||||||
vmin = std::min(vmin, v);
|
vmin = std::min(vmin, v);
|
||||||
|
@ -576,93 +556,91 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
vmax -= vmin;
|
vmax -= vmin;
|
||||||
const IfcFloat diag = vmax.Length();
|
const IfcFloat diag = vmax.Length();
|
||||||
|
IfcVector3 dir = IfcMatrix3(trafo) * extrusionDir;
|
||||||
IfcVector3 min = in[0];
|
|
||||||
dir *= IfcMatrix3(trafo);
|
|
||||||
|
|
||||||
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
||||||
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal( in.data(), in.size());
|
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(in.data(), in.size());
|
||||||
if( profileNormal * dir < 0.0 )
|
if( profileNormal * dir < 0.0 )
|
||||||
std::reverse( in.begin(), in.end());
|
std::reverse(in.begin(), in.end());
|
||||||
|
|
||||||
std::vector<IfcVector3> nors;
|
std::vector<IfcVector3> nors;
|
||||||
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
||||||
|
|
||||||
// Compute the normal vectors for all opening polygons as a prerequisite
|
// Compute the normal vectors for all opening polygons as a prerequisite
|
||||||
// to TryAddOpenings_Poly2Tri()
|
// to TryAddOpenings_Poly2Tri()
|
||||||
// XXX this belongs into the aforementioned function
|
// XXX this belongs into the aforementioned function
|
||||||
if (openings) {
|
if( openings ) {
|
||||||
|
|
||||||
if (!conv.settings.useCustomTriangulation) {
|
if( !conv.settings.useCustomTriangulation ) {
|
||||||
// it is essential to apply the openings in the correct spatial order. The direction
|
// it is essential to apply the openings in the correct spatial order. The direction
|
||||||
// doesn't matter, but we would screw up if we started with e.g. a door in between
|
// doesn't matter, but we would screw up if we started with e.g. a door in between
|
||||||
// two windows.
|
// two windows.
|
||||||
std::sort(conv.apply_openings->begin(),conv.apply_openings->end(),
|
std::sort(conv.apply_openings->begin(), conv.apply_openings->end(), TempOpening::DistanceSorter(in[0]));
|
||||||
TempOpening::DistanceSorter(min));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nors.reserve(conv.apply_openings->size());
|
nors.reserve(conv.apply_openings->size());
|
||||||
BOOST_FOREACH(TempOpening& t,*conv.apply_openings) {
|
BOOST_FOREACH(TempOpening& t, *conv.apply_openings) {
|
||||||
TempMesh& bounds = *t.profileMesh.get();
|
TempMesh& bounds = *t.profileMesh.get();
|
||||||
|
|
||||||
if (bounds.verts.size() <= 2) {
|
if( bounds.verts.size() <= 2 ) {
|
||||||
nors.push_back(IfcVector3());
|
nors.push_back(IfcVector3());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nors.push_back(((bounds.verts[2]-bounds.verts[0])^(bounds.verts[1]-bounds.verts[0]) ).Normalize());
|
nors.push_back(((bounds.verts[2] - bounds.verts[0]) ^ (bounds.verts[1] - bounds.verts[0])).Normalize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TempMesh temp;
|
TempMesh temp;
|
||||||
TempMesh& curmesh = openings ? temp : result;
|
TempMesh& curmesh = openings ? temp : result;
|
||||||
std::vector<IfcVector3>& out = curmesh.verts;
|
std::vector<IfcVector3>& out = curmesh.verts;
|
||||||
|
|
||||||
size_t sides_with_openings = 0;
|
size_t sides_with_openings = 0;
|
||||||
for(size_t i = 0; i < size; ++i) {
|
for( size_t i = 0; i < in.size(); ++i ) {
|
||||||
const size_t next = (i+1)%size;
|
const size_t next = (i + 1) % in.size();
|
||||||
|
|
||||||
curmesh.vertcnt.push_back(4);
|
curmesh.vertcnt.push_back(4);
|
||||||
|
|
||||||
out.push_back(in[i]);
|
out.push_back(in[i]);
|
||||||
out.push_back(in[next]);
|
out.push_back(in[next]);
|
||||||
out.push_back(in[next]+dir);
|
out.push_back(in[next] + dir);
|
||||||
out.push_back(in[i]+dir);
|
out.push_back(in[i] + dir);
|
||||||
|
|
||||||
if(openings) {
|
if( openings ) {
|
||||||
if((in[i]-in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
if( (in[i] - in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||||
++sides_with_openings;
|
++sides_with_openings;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Append(temp);
|
result.Append(temp);
|
||||||
temp.Clear();
|
temp.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openings) {
|
if( openings ) {
|
||||||
BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
|
BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
|
||||||
if (!opening.wallPoints.empty()) {
|
if( !opening.wallPoints.empty() ) {
|
||||||
IFCImporter::LogError("failed to generate all window caps");
|
IFCImporter::LogError("failed to generate all window caps");
|
||||||
}
|
}
|
||||||
opening.wallPoints.clear();
|
opening.wallPoints.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sides_with_v_openings = 0;
|
|
||||||
if(has_area) {
|
|
||||||
|
|
||||||
for(size_t n = 0; n < 2; ++n) {
|
size_t sides_with_v_openings = 0;
|
||||||
|
if( has_area ) {
|
||||||
|
|
||||||
|
for( size_t n = 0; n < 2; ++n ) {
|
||||||
if( n > 0 ) {
|
if( n > 0 ) {
|
||||||
for(size_t i = 0; i < size; ++i )
|
for( size_t i = 0; i < in.size(); ++i )
|
||||||
out.push_back(in[i]+dir);
|
out.push_back(in[i] + dir);
|
||||||
} else {
|
}
|
||||||
for(size_t i = size; i--; )
|
else {
|
||||||
|
for( size_t i = in.size(); i--; )
|
||||||
out.push_back(in[i]);
|
out.push_back(in[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
curmesh.vertcnt.push_back(size);
|
curmesh.vertcnt.push_back(in.size());
|
||||||
if(openings && size > 2) {
|
if( openings && in.size() > 2 ) {
|
||||||
if(GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
if( GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||||
++sides_with_v_openings;
|
++sides_with_v_openings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +650,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings))) {
|
if( openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings)) ) {
|
||||||
IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
|
IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,17 +658,58 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
||||||
|
|
||||||
// If this is an opening element, store both the extruded mesh and the 2D profile mesh
|
// If this is an opening element, store both the extruded mesh and the 2D profile mesh
|
||||||
// it was created from. Return an empty mesh to the caller.
|
// it was created from. Return an empty mesh to the caller.
|
||||||
if(collect_openings && !result.IsEmpty()) {
|
if( collect_openings && !result.IsEmpty() ) {
|
||||||
ai_assert(conv.collect_openings);
|
ai_assert(conv.collect_openings);
|
||||||
boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
|
boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||||
profile->Swap(result);
|
profile->Swap(result);
|
||||||
|
|
||||||
boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
|
boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||||
profile2D->Swap(meshout);
|
profile2D->verts.insert(profile2D->verts.end(), in.begin(), in.end());
|
||||||
conv.collect_openings->push_back(TempOpening(&solid,dir,profile, profile2D));
|
profile2D->vertcnt.push_back(in.size());
|
||||||
|
conv.collect_openings->push_back(TempOpening(&solid, dir, profile, profile2D));
|
||||||
|
|
||||||
ai_assert(result.IsEmpty());
|
ai_assert(result.IsEmpty());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
|
||||||
|
ConversionData& conv, bool collect_openings)
|
||||||
|
{
|
||||||
|
TempMesh meshout;
|
||||||
|
|
||||||
|
// First read the profile description.
|
||||||
|
if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcVector3 dir;
|
||||||
|
ConvertDirection(dir,solid.ExtrudedDirection);
|
||||||
|
dir *= solid.Depth;
|
||||||
|
|
||||||
|
// Some profiles bring their own holes, for which we need to provide a container. This all is somewhat backwards,
|
||||||
|
// and there's still so many corner cases uncovered - we really need a generic solution to all of this hole carving.
|
||||||
|
std::vector<TempOpening> fisherPriceMyFirstOpenings;
|
||||||
|
std::vector<TempOpening>* oldApplyOpenings = conv.apply_openings;
|
||||||
|
if( const IfcArbitraryProfileDefWithVoids* const cprofile = solid.SweptArea->ToPtr<IfcArbitraryProfileDefWithVoids>() ) {
|
||||||
|
if( !cprofile->InnerCurves.empty() ) {
|
||||||
|
// read all inner curves and extrude them to form proper openings.
|
||||||
|
std::vector<TempOpening>* oldCollectOpenings = conv.collect_openings;
|
||||||
|
conv.collect_openings = &fisherPriceMyFirstOpenings;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const IfcCurve* curve, cprofile->InnerCurves) {
|
||||||
|
TempMesh curveMesh, tempMesh;
|
||||||
|
ProcessCurve(*curve, curveMesh, conv);
|
||||||
|
ProcessExtrudedArea(solid, curveMesh, dir, tempMesh, conv, true);
|
||||||
|
}
|
||||||
|
// and then apply those to the geometry we're about to generate
|
||||||
|
conv.apply_openings = conv.collect_openings;
|
||||||
|
conv.collect_openings = oldCollectOpenings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessExtrudedArea(solid, meshout, dir, result, conv, collect_openings);
|
||||||
|
conv.apply_openings = oldApplyOpenings;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -785,7 +804,7 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, unsigned int matid,
|
||||||
meshtmp->RemoveDegenerates();
|
meshtmp->RemoveDegenerates();
|
||||||
|
|
||||||
if(fix_orientation) {
|
if(fix_orientation) {
|
||||||
meshtmp->FixupFaceOrientation();
|
// meshtmp->FixupFaceOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMesh* const mesh = meshtmp->ToMesh();
|
aiMesh* const mesh = meshtmp->ToMesh();
|
||||||
|
|
|
@ -680,10 +680,11 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
const STEP::DB::RefMap& refs = conv.db.GetRefs();
|
const STEP::DB::RefMap& refs = conv.db.GetRefs();
|
||||||
|
|
||||||
// skip over space and annotation nodes - usually, these have no meaning in Assimp's context
|
// skip over space and annotation nodes - usually, these have no meaning in Assimp's context
|
||||||
|
bool skipGeometry = false;
|
||||||
if(conv.settings.skipSpaceRepresentations) {
|
if(conv.settings.skipSpaceRepresentations) {
|
||||||
if(const IfcSpace* const space = el.ToPtr<IfcSpace>()) {
|
if(const IfcSpace* const space = el.ToPtr<IfcSpace>()) {
|
||||||
IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
|
IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
|
||||||
return NULL;
|
skipGeometry = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,8 +854,10 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
|
||||||
conv.apply_openings = &openings;
|
conv.apply_openings = &openings;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessProductRepresentation(el,nd.get(),subnodes,conv);
|
if (!skipGeometry) {
|
||||||
conv.apply_openings = conv.collect_openings = NULL;
|
ProcessProductRepresentation(el,nd.get(),subnodes,conv);
|
||||||
|
conv.apply_openings = conv.collect_openings = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (subnodes.size()) {
|
if (subnodes.size()) {
|
||||||
nd->mChildren = new aiNode*[subnodes.size()]();
|
nd->mChildren = new aiNode*[subnodes.size()]();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
7622
code/IFCReaderGen.h
7622
code/IFCReaderGen.h
File diff suppressed because it is too large
Load Diff
|
@ -236,7 +236,7 @@ IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
|
||||||
|
|
||||||
struct CompareVector
|
struct CompareVector
|
||||||
{
|
{
|
||||||
bool operator () (const IfcVector3& a, const IfcVector3& b)
|
bool operator () (const IfcVector3& a, const IfcVector3& b) const
|
||||||
{
|
{
|
||||||
IfcVector3 d = a - b;
|
IfcVector3 d = a - b;
|
||||||
IfcFloat eps = 1e-6;
|
IfcFloat eps = 1e-6;
|
||||||
|
|
|
@ -277,6 +277,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix);
|
||||||
|
|
||||||
// IFCProfile.cpp
|
// IFCProfile.cpp
|
||||||
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
||||||
|
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
|
||||||
|
|
||||||
// IFCMaterial.cpp
|
// IFCMaterial.cpp
|
||||||
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
|
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -140,6 +140,9 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
||||||
# include "OgreImporter.h"
|
# include "OgreImporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||||
|
# include "OpenGEXImporter.h"
|
||||||
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
||||||
# include "MS3DLoader.h"
|
# include "MS3DLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,132 +180,135 @@ namespace Assimp {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
{
|
{
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Add an instance of each worker class here
|
// Add an instance of each worker class here
|
||||||
// (register_new_importers_here)
|
// (register_new_importers_here)
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
out.reserve(64);
|
out.reserve(64);
|
||||||
#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
|
||||||
out.push_back( new XFileImporter());
|
out.push_back( new XFileImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
|
||||||
out.push_back( new ObjFileImporter());
|
out.push_back( new ObjFileImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
|
||||||
out.push_back( new Discreet3DSImporter());
|
out.push_back( new Discreet3DSImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
|
||||||
out.push_back( new MD3Importer());
|
out.push_back( new MD3Importer());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
|
||||||
out.push_back( new MD2Importer());
|
out.push_back( new MD2Importer());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
|
||||||
out.push_back( new PLYImporter());
|
out.push_back( new PLYImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
|
||||||
out.push_back( new MDLImporter());
|
out.push_back( new MDLImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
|
||||||
out.push_back( new ASEImporter());
|
out.push_back( new ASEImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
|
||||||
out.push_back( new HMPImporter());
|
out.push_back( new HMPImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
|
||||||
out.push_back( new SMDImporter());
|
out.push_back( new SMDImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
|
||||||
out.push_back( new MDCImporter());
|
out.push_back( new MDCImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
|
||||||
out.push_back( new MD5Importer());
|
out.push_back( new MD5Importer());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
|
||||||
out.push_back( new STLImporter());
|
out.push_back( new STLImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
|
||||||
out.push_back( new LWOImporter());
|
out.push_back( new LWOImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
|
||||||
out.push_back( new DXFImporter());
|
out.push_back( new DXFImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
|
||||||
out.push_back( new NFFImporter());
|
out.push_back( new NFFImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
|
||||||
out.push_back( new RAWImporter());
|
out.push_back( new RAWImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
|
||||||
out.push_back( new OFFImporter());
|
out.push_back( new OFFImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
|
||||||
out.push_back( new AC3DImporter());
|
out.push_back( new AC3DImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
|
||||||
out.push_back( new BVHLoader());
|
out.push_back( new BVHLoader());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
|
||||||
out.push_back( new IRRMeshImporter());
|
out.push_back( new IRRMeshImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
|
||||||
out.push_back( new IRRImporter());
|
out.push_back( new IRRImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
|
||||||
out.push_back( new Q3DImporter());
|
out.push_back( new Q3DImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
|
||||||
out.push_back( new B3DImporter());
|
out.push_back( new B3DImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
|
||||||
out.push_back( new ColladaLoader());
|
out.push_back( new ColladaLoader());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
|
||||||
out.push_back( new TerragenImporter());
|
out.push_back( new TerragenImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
|
||||||
out.push_back( new CSMImporter());
|
out.push_back( new CSMImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
|
||||||
out.push_back( new UnrealImporter());
|
out.push_back( new UnrealImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
|
||||||
out.push_back( new LWSImporter());
|
out.push_back( new LWSImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
|
||||||
out.push_back( new Ogre::OgreImporter());
|
out.push_back( new Ogre::OgreImporter());
|
||||||
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_OPENGEX_IMPORTER )
|
||||||
|
out.push_back( new OpenGEX::OpenGEXImporter() );
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
|
||||||
out.push_back( new MS3DImporter());
|
out.push_back( new MS3DImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
|
||||||
out.push_back( new COBImporter());
|
out.push_back( new COBImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
|
||||||
out.push_back( new BlenderImporter());
|
out.push_back( new BlenderImporter());
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
|
||||||
out.push_back( new Q3BSPFileImporter() );
|
out.push_back( new Q3BSPFileImporter() );
|
||||||
#endif
|
#endif
|
||||||
#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
|
#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
|
||||||
out.push_back( new NDOImporter() );
|
out.push_back( new NDOImporter() );
|
||||||
#endif
|
#endif
|
||||||
#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_XGL_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER )
|
||||||
out.push_back( new XGLImporter() );
|
out.push_back( new XGLImporter() );
|
||||||
#endif
|
#endif
|
||||||
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
|
||||||
out.push_back( new FBXImporter() );
|
out.push_back( new FBXImporter() );
|
||||||
#endif
|
#endif
|
||||||
#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER )
|
||||||
out.push_back( new AssbinImporter() );
|
out.push_back( new AssbinImporter() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
out.push_back( new C4DImporter() );
|
out.push_back( new C4DImporter() );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Assimp
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
ObjExporter exporter(pFile, pScene);
|
ObjExporter exporter(pFile, pScene);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -65,57 +65,59 @@ struct Model;
|
||||||
class ObjFileImporter : public BaseImporter
|
class ObjFileImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// \brief Default constructor
|
/// \brief Default constructor
|
||||||
ObjFileImporter();
|
ObjFileImporter();
|
||||||
|
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
~ObjFileImporter();
|
~ObjFileImporter();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Returns whether the class can handle the format of the given file.
|
/// \brief Returns whether the class can handle the format of the given file.
|
||||||
/// \remark See BaseImporter::CanRead() for details.
|
/// \remark See BaseImporter::CanRead() for details.
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! \brief Appends the supported extension.
|
//! \brief Appends the supported extension.
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
//! \brief File import implementation.
|
//! \brief File import implementation.
|
||||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
//! \brief Create the data from imported content.
|
//! \brief Create the data from imported content.
|
||||||
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
||||||
|
|
||||||
//! \brief Creates all nodes stored in imported content.
|
//! \brief Creates all nodes stored in imported content.
|
||||||
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||||
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
||||||
|
|
||||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||||
aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||||
unsigned int uiMeshIndex );
|
unsigned int uiMeshIndex );
|
||||||
|
|
||||||
//! \brief Creates vertices from model.
|
//! \brief Creates vertices from model.
|
||||||
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
|
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
|
||||||
unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
|
unsigned int uiMeshIndex, aiMesh* pMesh, unsigned int numIndices );
|
||||||
|
|
||||||
//! \brief Object counter helper method.
|
//! \brief Object counter helper method.
|
||||||
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
|
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
|
||||||
|
|
||||||
//! \brief Material creation.
|
//! \brief Material creation.
|
||||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||||
void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
|
|
||||||
|
/// @brief Adds special property for the used texture mapping mode of the model.
|
||||||
|
void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
|
||||||
|
|
||||||
//! \brief Appends a child node to a parent node and updates the data structures.
|
//! \brief Appends a child node to a parent node and updates the data structures.
|
||||||
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Data buffer
|
//! Data buffer
|
||||||
std::vector<char> m_Buffer;
|
std::vector<char> m_Buffer;
|
||||||
//! Pointer to root object instance
|
//! Pointer to root object instance
|
||||||
ObjFile::Object *m_pRootObject;
|
ObjFile::Object *m_pRootObject;
|
||||||
//! Absolute pathname of model in file system
|
//! Absolute pathname of model in file system
|
||||||
std::string m_strAbsPath;
|
std::string m_strAbsPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -66,76 +66,76 @@ class IOSystem;
|
||||||
class ObjFileParser
|
class ObjFileParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const size_t BUFFERSIZE = 4096;
|
static const size_t BUFFERSIZE = 4096;
|
||||||
typedef std::vector<char> DataArray;
|
typedef std::vector<char> DataArray;
|
||||||
typedef std::vector<char>::iterator DataArrayIt;
|
typedef std::vector<char>::iterator DataArrayIt;
|
||||||
typedef std::vector<char>::const_iterator ConstDataArrayIt;
|
typedef std::vector<char>::const_iterator ConstDataArrayIt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Constructor with data array.
|
/// \brief Constructor with data array.
|
||||||
ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
|
ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
~ObjFileParser();
|
~ObjFileParser();
|
||||||
/// \brief Model getter.
|
/// \brief Model getter.
|
||||||
ObjFile::Model *GetModel() const;
|
ObjFile::Model *GetModel() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parse the loaded file
|
/// Parse the loaded file
|
||||||
void parseFile();
|
void parseFile();
|
||||||
/// Method to copy the new delimited word in the current line.
|
/// Method to copy the new delimited word in the current line.
|
||||||
void copyNextWord(char *pBuffer, size_t length);
|
void copyNextWord(char *pBuffer, size_t length);
|
||||||
/// Method to copy the new line.
|
/// Method to copy the new line.
|
||||||
void copyNextLine(char *pBuffer, size_t length);
|
void copyNextLine(char *pBuffer, size_t length);
|
||||||
/// Stores the vector
|
/// Stores the vector
|
||||||
void getVector( std::vector<aiVector3D> &point3d_array );
|
void getVector( std::vector<aiVector3D> &point3d_array );
|
||||||
/// Stores the following 3d vector.
|
/// Stores the following 3d vector.
|
||||||
void getVector3( std::vector<aiVector3D> &point3d_array );
|
void getVector3( std::vector<aiVector3D> &point3d_array );
|
||||||
/// Stores the following 3d vector.
|
/// Stores the following 3d vector.
|
||||||
void getVector2(std::vector<aiVector2D> &point2d_array);
|
void getVector2(std::vector<aiVector2D> &point2d_array);
|
||||||
/// Stores the following face.
|
/// Stores the following face.
|
||||||
void getFace(aiPrimitiveType type);
|
void getFace(aiPrimitiveType type);
|
||||||
/// Reads the material description.
|
/// Reads the material description.
|
||||||
void getMaterialDesc();
|
void getMaterialDesc();
|
||||||
/// Gets a comment.
|
/// Gets a comment.
|
||||||
void getComment();
|
void getComment();
|
||||||
/// Gets a a material library.
|
/// Gets a a material library.
|
||||||
void getMaterialLib();
|
void getMaterialLib();
|
||||||
/// Creates a new material.
|
/// Creates a new material.
|
||||||
void getNewMaterial();
|
void getNewMaterial();
|
||||||
/// Gets the group name from file.
|
/// Gets the group name from file.
|
||||||
void getGroupName();
|
void getGroupName();
|
||||||
/// Gets the group number from file.
|
/// Gets the group number from file.
|
||||||
void getGroupNumber();
|
void getGroupNumber();
|
||||||
/// Gets the group number and resolution from file.
|
/// Gets the group number and resolution from file.
|
||||||
void getGroupNumberAndResolution();
|
void getGroupNumberAndResolution();
|
||||||
/// Returns the index of the material. Is -1 if not material was found.
|
/// Returns the index of the material. Is -1 if not material was found.
|
||||||
int getMaterialIndex( const std::string &strMaterialName );
|
int getMaterialIndex( const std::string &strMaterialName );
|
||||||
/// Parse object name
|
/// Parse object name
|
||||||
void getObjectName();
|
void getObjectName();
|
||||||
/// Creates a new object.
|
/// Creates a new object.
|
||||||
void createObject(const std::string &strObjectName);
|
void createObject(const std::string &strObjectName);
|
||||||
/// Creates a new mesh.
|
/// Creates a new mesh.
|
||||||
void createMesh();
|
void createMesh();
|
||||||
/// Returns true, if a new mesh instance must be created.
|
/// Returns true, if a new mesh instance must be created.
|
||||||
bool needsNewMesh( const std::string &rMaterialName );
|
bool needsNewMesh( const std::string &rMaterialName );
|
||||||
/// Error report in token
|
/// Error report in token
|
||||||
void reportErrorTokenInFace();
|
void reportErrorTokenInFace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Default material name
|
/// Default material name
|
||||||
static const std::string DEFAULT_MATERIAL;
|
static const std::string DEFAULT_MATERIAL;
|
||||||
//! Iterator to current position in buffer
|
//! Iterator to current position in buffer
|
||||||
DataArrayIt m_DataIt;
|
DataArrayIt m_DataIt;
|
||||||
//! Iterator to end position of buffer
|
//! Iterator to end position of buffer
|
||||||
DataArrayIt m_DataItEnd;
|
DataArrayIt m_DataItEnd;
|
||||||
//! Pointer to model instance
|
//! Pointer to model instance
|
||||||
ObjFile::Model *m_pModel;
|
ObjFile::Model *m_pModel;
|
||||||
//! Current line (for debugging)
|
//! Current line (for debugging)
|
||||||
unsigned int m_uiLine;
|
unsigned int m_uiLine;
|
||||||
//! Helper buffer
|
//! Helper buffer
|
||||||
char m_buffer[BUFFERSIZE];
|
char m_buffer[BUFFERSIZE];
|
||||||
/// Pointer to IO system instance.
|
/// Pointer to IO system instance.
|
||||||
IOSystem *m_pIO;
|
IOSystem *m_pIO;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
|
@ -0,0 +1,866 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2014, 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 ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
#include "OpenGEXImporter.h"
|
||||||
|
#include "DefaultIOSystem.h"
|
||||||
|
#include "MakeVerboseFormat.h"
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLParser.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static const aiImporterDesc desc = {
|
||||||
|
"Open Game Engine Exchange",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
aiImporterFlags_SupportTextFlavour,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"ogex"
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Grammar {
|
||||||
|
static const char *MetricType = "Metric";
|
||||||
|
static const char *Metric_DistanceType = "distance";
|
||||||
|
static const char *Metric_AngleType = "angle";
|
||||||
|
static const char *Metric_TimeType = "time";
|
||||||
|
static const char *Metric_UpType = "up";
|
||||||
|
static const char *NameType = "Name";
|
||||||
|
static const char *ObjectRefType = "ObjectRef";
|
||||||
|
static const char *MaterialRefType = "MaterialRef";
|
||||||
|
static const char *MetricKeyType = "key";
|
||||||
|
static const char *GeometryNodeType = "GeometryNode";
|
||||||
|
static const char *GeometryObjectType = "GeometryObject";
|
||||||
|
static const char *TransformType = "Transform";
|
||||||
|
static const char *MeshType = "Mesh";
|
||||||
|
static const char *VertexArrayType = "VertexArray";
|
||||||
|
static const char *IndexArrayType = "IndexArray";
|
||||||
|
static const char *MaterialType = "Material";
|
||||||
|
static const char *ColorType = "Color";
|
||||||
|
static const char *TextureType = "Texture";
|
||||||
|
|
||||||
|
enum TokenType {
|
||||||
|
NoneType = -1,
|
||||||
|
MetricToken,
|
||||||
|
NameToken,
|
||||||
|
ObjectRefToken,
|
||||||
|
MaterialRefToken,
|
||||||
|
MetricKeyToken,
|
||||||
|
GeometryNodeToken,
|
||||||
|
GeometryObjectToken,
|
||||||
|
TransformToken,
|
||||||
|
MeshToken,
|
||||||
|
VertexArrayToken,
|
||||||
|
IndexArrayToken,
|
||||||
|
MaterialToken,
|
||||||
|
ColorToken,
|
||||||
|
TextureToken
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *ValidMetricToken[ 4 ] = {
|
||||||
|
Metric_DistanceType,
|
||||||
|
Metric_AngleType,
|
||||||
|
Metric_TimeType,
|
||||||
|
Metric_UpType
|
||||||
|
};
|
||||||
|
|
||||||
|
static int isValidMetricType( const char *token ) {
|
||||||
|
if( NULL == token ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx( -1 );
|
||||||
|
for( size_t i = 0; i < 4; i++ ) {
|
||||||
|
if( 0 == strncmp( ValidMetricToken[ i ], token, strlen( token ) ) ) {
|
||||||
|
idx = (int) i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TokenType matchTokenType( const char *tokenType ) {
|
||||||
|
if( 0 == strncmp( MetricType, tokenType, strlen( MetricType ) ) ) {
|
||||||
|
return MetricToken;
|
||||||
|
} else if( 0 == strncmp( NameType, tokenType, strlen( NameType ) ) ) {
|
||||||
|
return NameToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( ObjectRefType, tokenType, strlen( ObjectRefType ) ) ) {
|
||||||
|
return ObjectRefToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( MaterialRefType, tokenType, strlen( MaterialRefType ) ) ) {
|
||||||
|
return MaterialRefToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( MetricKeyType, tokenType, strlen( MetricKeyType ) ) ) {
|
||||||
|
return MetricKeyToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( GeometryNodeType ) ) ) {
|
||||||
|
return GeometryNodeToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( GeometryObjectType ) ) ) {
|
||||||
|
return GeometryObjectToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( TransformType, tokenType, strlen( TransformType ) ) ) {
|
||||||
|
return TransformToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( MeshType, tokenType, strlen( MeshType ) ) ) {
|
||||||
|
return MeshToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( VertexArrayType, tokenType, strlen( VertexArrayType ) ) ) {
|
||||||
|
return VertexArrayToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( IndexArrayType, tokenType, strlen( IndexArrayType ) ) ) {
|
||||||
|
return IndexArrayToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( MaterialType, tokenType, strlen( MaterialType ) ) ) {
|
||||||
|
return MaterialToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( ColorType, tokenType, strlen( ColorType ) ) ) {
|
||||||
|
return ColorToken;
|
||||||
|
}
|
||||||
|
else if( 0 == strncmp( TextureType, tokenType, strlen( TextureType ) ) ) {
|
||||||
|
return TextureToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoneType;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace Grammar
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace OpenGEX {
|
||||||
|
|
||||||
|
USE_ODDLPARSER_NS
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::VertexContainer::VertexContainer()
|
||||||
|
: m_numVerts( 0 )
|
||||||
|
, m_vertices()
|
||||||
|
, m_numNormals( 0 )
|
||||||
|
, m_normals()
|
||||||
|
, m_textureCoords()
|
||||||
|
, m_numUVComps() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::VertexContainer::~VertexContainer() {
|
||||||
|
delete[] m_vertices;
|
||||||
|
delete[] m_normals;
|
||||||
|
for( size_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ ) {
|
||||||
|
delete [] m_textureCoords[ i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector<std::string> &names )
|
||||||
|
: m_node( node )
|
||||||
|
, m_type( type )
|
||||||
|
, m_Names( names ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::RefInfo::~RefInfo() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::OpenGEXImporter()
|
||||||
|
: m_meshCache()
|
||||||
|
, m_root( NULL )
|
||||||
|
, m_nodeChildMap()
|
||||||
|
, m_mesh2refMap()
|
||||||
|
, m_ctx( NULL )
|
||||||
|
, m_currentNode( NULL )
|
||||||
|
, m_currentMesh( NULL )
|
||||||
|
, m_nodeStack()
|
||||||
|
, m_unresolvedRefStack() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
OpenGEXImporter::~OpenGEXImporter() {
|
||||||
|
m_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
|
||||||
|
bool canRead( false );
|
||||||
|
if( !checkSig ) {
|
||||||
|
canRead = SimpleExtensionCheck( file, "ogex" );
|
||||||
|
} else {
|
||||||
|
static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
|
||||||
|
canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return canRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) {
|
||||||
|
// open source file
|
||||||
|
IOStream *file = pIOHandler->Open( filename, "rb" );
|
||||||
|
if( !file ) {
|
||||||
|
throw DeadlyImportError( "Failed to open file " + filename );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> buffer;
|
||||||
|
TextFileToBuffer( file, buffer );
|
||||||
|
|
||||||
|
OpenDDLParser myParser;
|
||||||
|
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
|
||||||
|
bool success( myParser.parse() );
|
||||||
|
if( success ) {
|
||||||
|
m_ctx = myParser.getContext();
|
||||||
|
pScene->mRootNode = new aiNode;
|
||||||
|
pScene->mRootNode->mName.Set( filename );
|
||||||
|
handleNodes( m_ctx->m_root, pScene );
|
||||||
|
}
|
||||||
|
|
||||||
|
copyMeshes( pScene );
|
||||||
|
resolveReferences();
|
||||||
|
createNodeTree( pScene );
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
const aiImporterDesc *OpenGEXImporter::GetInfo() const {
|
||||||
|
return &desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
|
||||||
|
if( NULL == pImp ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == node ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode::DllNodeList childs = node->getChildNodeList();
|
||||||
|
for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); it++ ) {
|
||||||
|
Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) );
|
||||||
|
switch( tokenType ) {
|
||||||
|
case Grammar::MetricToken:
|
||||||
|
handleMetricNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::NameToken:
|
||||||
|
handleNameNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::ObjectRefToken:
|
||||||
|
handleObjectRefNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::MaterialRefToken:
|
||||||
|
handleMaterialRefNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::MetricKeyToken:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::GeometryNodeToken:
|
||||||
|
handleGeometryNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::GeometryObjectToken:
|
||||||
|
handleGeometryObject( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::TransformToken:
|
||||||
|
handleTransformNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::MeshToken:
|
||||||
|
handleMeshNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::VertexArrayToken:
|
||||||
|
handleVertexArrayNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::IndexArrayToken:
|
||||||
|
handleIndexArrayNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::MaterialToken:
|
||||||
|
handleMaterialNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::ColorToken:
|
||||||
|
handleColorNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Grammar::TextureToken:
|
||||||
|
handleTextureNode( *it, pScene );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == node || NULL == m_ctx ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_ctx->m_root != node->getParent() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property *prop( node->getProperties() );
|
||||||
|
while( NULL != prop ) {
|
||||||
|
if( NULL != prop->m_id ) {
|
||||||
|
if( Value::ddl_string == prop->m_primData->m_type ) {
|
||||||
|
std::string valName( (char*) prop->m_primData->m_data );
|
||||||
|
int type( Grammar::isValidMetricType( valName.c_str() ) );
|
||||||
|
if( Grammar::NoneType != type ) {
|
||||||
|
Value *val( node->getValue() );
|
||||||
|
if( NULL != val ) {
|
||||||
|
if( Value::ddl_float == val->m_type ) {
|
||||||
|
m_metrics[ type ].m_floatValue = val->getFloat();
|
||||||
|
} else if( Value::ddl_int32 == val->m_type ) {
|
||||||
|
m_metrics[ type ].m_intValue = val->getInt32();
|
||||||
|
} else if( Value::ddl_string == val->m_type ) {
|
||||||
|
m_metrics[type].m_stringValue = std::string( val->getString() );
|
||||||
|
} else {
|
||||||
|
throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop = prop->m_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == m_currentNode ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *val( node->getValue() );
|
||||||
|
if( NULL != val ) {
|
||||||
|
if( Value::ddl_string != val->m_type ) {
|
||||||
|
throw DeadlyImportError( "OpenGEX: invalid data type for value in node name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string name( val->getString() );
|
||||||
|
m_currentNode->mName.Set( name.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
|
||||||
|
ai_assert( NULL != node );
|
||||||
|
|
||||||
|
Reference *ref = node->getReferences();
|
||||||
|
if( NULL != ref ) {
|
||||||
|
for( size_t i = 0; i < ref->m_numRefs; i++ ) {
|
||||||
|
Name *currentName( ref->m_referencedName[ i ] );
|
||||||
|
if( NULL != currentName && NULL != currentName->m_id ) {
|
||||||
|
const std::string name( currentName->m_id->m_buffer );
|
||||||
|
if( !name.empty() ) {
|
||||||
|
names.push_back( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == m_currentNode ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> objRefNames;
|
||||||
|
getRefNames( node, objRefNames );
|
||||||
|
m_currentNode->mNumMeshes = objRefNames.size();
|
||||||
|
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||||
|
if( !objRefNames.empty() ) {
|
||||||
|
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == m_currentNode ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> matRefNames;
|
||||||
|
getRefNames( node, matRefNames );
|
||||||
|
if( !matRefNames.empty() ) {
|
||||||
|
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) {
|
||||||
|
aiNode *newNode = new aiNode;
|
||||||
|
pushNode( newNode, pScene );
|
||||||
|
m_currentNode = newNode;
|
||||||
|
handleNodes( node, pScene );
|
||||||
|
|
||||||
|
popNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) {
|
||||||
|
handleNodes( node, pScene );
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void setMatrix( aiNode *node, DataArrayList *transformData ) {
|
||||||
|
ai_assert( NULL != node );
|
||||||
|
ai_assert( NULL != transformData );
|
||||||
|
|
||||||
|
float m[ 16 ];
|
||||||
|
size_t i( 1 );
|
||||||
|
Value *next( transformData->m_dataList->m_next );
|
||||||
|
m[ 0 ] = transformData->m_dataList->getFloat();
|
||||||
|
while( next != NULL ) {
|
||||||
|
m[ i ] = next->getFloat();
|
||||||
|
next = next->m_next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->mTransformation.a1 = m[ 0 ];
|
||||||
|
node->mTransformation.a2 = m[ 1 ];
|
||||||
|
node->mTransformation.a3 = m[ 2 ];
|
||||||
|
node->mTransformation.a4 = m[ 3 ];
|
||||||
|
|
||||||
|
node->mTransformation.b1 = m[ 4 ];
|
||||||
|
node->mTransformation.b2 = m[ 5 ];
|
||||||
|
node->mTransformation.b3 = m[ 6 ];
|
||||||
|
node->mTransformation.b4 = m[ 7 ];
|
||||||
|
|
||||||
|
node->mTransformation.c1 = m[ 8 ];
|
||||||
|
node->mTransformation.c2 = m[ 9 ];
|
||||||
|
node->mTransformation.c3 = m[ 10 ];
|
||||||
|
node->mTransformation.c4 = m[ 11 ];
|
||||||
|
|
||||||
|
node->mTransformation.d1 = m[ 12 ];
|
||||||
|
node->mTransformation.d2 = m[ 13 ];
|
||||||
|
node->mTransformation.d3 = m[ 14 ];
|
||||||
|
node->mTransformation.d4 = m[ 15 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == m_currentNode ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DataArrayList *transformData( node->getDataArrayList() );
|
||||||
|
if( NULL != transformData ) {
|
||||||
|
if( transformData->m_numItems != 16 ) {
|
||||||
|
throw DeadlyImportError( "Invalid number of data for transform matrix." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setMatrix( m_currentNode, transformData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void propId2StdString( Property *prop, std::string &name, std::string &key ) {
|
||||||
|
name = key = "";
|
||||||
|
if( NULL == prop ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( NULL != prop->m_id ) {
|
||||||
|
name = prop->m_id->m_buffer;
|
||||||
|
if( Value::ddl_string == prop->m_primData->m_type ) {
|
||||||
|
key = prop->m_primData->getString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
m_currentMesh = new aiMesh;
|
||||||
|
const size_t meshidx( m_meshCache.size() );
|
||||||
|
m_meshCache.push_back( m_currentMesh );
|
||||||
|
|
||||||
|
Property *prop = node->getProperties();
|
||||||
|
if( NULL != prop ) {
|
||||||
|
std::string propName, propKey;
|
||||||
|
propId2StdString( prop, propName, propKey );
|
||||||
|
if( "primitive" == propName ) {
|
||||||
|
if( "triangles" == propKey ) {
|
||||||
|
m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNodes( node, pScene );
|
||||||
|
|
||||||
|
DDLNode *parent( node->getParent() );
|
||||||
|
if( NULL != parent ) {
|
||||||
|
const std::string &name = parent->getName();
|
||||||
|
m_mesh2refMap[ name ] = meshidx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
enum MeshAttribute {
|
||||||
|
None,
|
||||||
|
Position,
|
||||||
|
Normal,
|
||||||
|
TexCoord
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static MeshAttribute getAttributeByName( const char *attribName ) {
|
||||||
|
ai_assert( NULL != attribName );
|
||||||
|
|
||||||
|
if( 0 == strncmp( "position", attribName, strlen( "position" ) ) ) {
|
||||||
|
return Position;
|
||||||
|
} else if( 0 == strncmp( "normal", attribName, strlen( "normal" ) ) ) {
|
||||||
|
return Normal;
|
||||||
|
} else if( 0 == strncmp( "texcoord", attribName, strlen( "texcoord" ) ) ) {
|
||||||
|
return TexCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void fillVector3( aiVector3D *vec3, Value *vals ) {
|
||||||
|
ai_assert( NULL != vec3 );
|
||||||
|
ai_assert( NULL != vals );
|
||||||
|
|
||||||
|
float x( 0.0f ), y( 0.0f ), z( 0.0f );
|
||||||
|
Value *next( vals );
|
||||||
|
x = next->getFloat();
|
||||||
|
next = next->m_next;
|
||||||
|
y = next->getFloat();
|
||||||
|
next = next->m_next;
|
||||||
|
if( NULL != next ) {
|
||||||
|
z = next->getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3->Set( x, y, z );
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static size_t countDataArrayListItems( DataArrayList *vaList ) {
|
||||||
|
size_t numItems( 0 );
|
||||||
|
if( NULL == vaList ) {
|
||||||
|
return numItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataArrayList *next( vaList );
|
||||||
|
while( NULL != next ) {
|
||||||
|
if( NULL != vaList->m_dataList ) {
|
||||||
|
numItems++;
|
||||||
|
}
|
||||||
|
next = next->m_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void copyVectorArray( size_t numItems, DataArrayList *vaList, aiVector3D *vectorArray ) {
|
||||||
|
for( size_t i = 0; i < numItems; i++ ) {
|
||||||
|
Value *next( vaList->m_dataList );
|
||||||
|
fillVector3( &vectorArray[ i ], next );
|
||||||
|
vaList = vaList->m_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == node ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property *prop( node->getProperties() );
|
||||||
|
if( NULL != prop ) {
|
||||||
|
std::string propName, propKey;
|
||||||
|
propId2StdString( prop, propName, propKey );
|
||||||
|
MeshAttribute attribType( getAttributeByName( propKey.c_str() ) );
|
||||||
|
if( None == attribType ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataArrayList *vaList = node->getDataArrayList();
|
||||||
|
if( NULL == vaList ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t numItems( countDataArrayListItems( vaList ) );
|
||||||
|
Value *next( vaList->m_dataList );
|
||||||
|
if( Position == attribType ) {
|
||||||
|
m_currentVertices.m_numVerts = numItems;
|
||||||
|
m_currentVertices.m_vertices = new aiVector3D[ numItems ];
|
||||||
|
copyVectorArray( numItems, vaList, m_currentVertices.m_vertices );
|
||||||
|
} else if( Normal == attribType ) {
|
||||||
|
m_currentVertices.m_numNormals = numItems;
|
||||||
|
m_currentVertices.m_normals = new aiVector3D[ numItems ];
|
||||||
|
copyVectorArray( numItems, vaList, m_currentVertices.m_normals );
|
||||||
|
} else if( TexCoord == attribType ) {
|
||||||
|
m_currentVertices.m_numUVComps[ 0 ] = numItems;
|
||||||
|
m_currentVertices.m_textureCoords[ 0 ] = new aiVector3D[ numItems ];
|
||||||
|
copyVectorArray( numItems, vaList, m_currentVertices.m_textureCoords[ 0 ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
if( NULL == node ) {
|
||||||
|
throw DeadlyImportError( "No parent node for name." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( NULL == m_currentMesh ) {
|
||||||
|
throw DeadlyImportError( "No current mesh for index data found." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataArrayList *vaList = node->getDataArrayList();
|
||||||
|
if( NULL == vaList ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t numItems( countDataArrayListItems( vaList ) );
|
||||||
|
m_currentMesh->mNumFaces = numItems;
|
||||||
|
m_currentMesh->mFaces = new aiFace[ numItems ];
|
||||||
|
m_currentMesh->mNumVertices = numItems * 3;
|
||||||
|
m_currentMesh->mVertices = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||||
|
m_currentMesh->mNormals = new aiVector3D[ m_currentMesh->mNumVertices ];
|
||||||
|
m_currentMesh->mNumUVComponents[ 0 ] = numItems * 3;
|
||||||
|
m_currentMesh->mTextureCoords[ 0 ] = new aiVector3D[ m_currentMesh->mNumUVComponents[ 0 ] ];
|
||||||
|
|
||||||
|
unsigned int index( 0 );
|
||||||
|
for( size_t i = 0; i < m_currentMesh->mNumFaces; i++ ) {
|
||||||
|
aiFace ¤t( m_currentMesh->mFaces[ i ] );
|
||||||
|
current.mNumIndices = 3;
|
||||||
|
current.mIndices = new unsigned int[ current.mNumIndices ];
|
||||||
|
Value *next( vaList->m_dataList );
|
||||||
|
for( size_t indices = 0; indices < current.mNumIndices; indices++ ) {
|
||||||
|
const int idx = next->getInt32();
|
||||||
|
ai_assert( idx <= m_currentVertices.m_numVerts );
|
||||||
|
|
||||||
|
aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] );
|
||||||
|
aiVector3D &normal = ( m_currentVertices.m_normals[ idx ] );
|
||||||
|
aiVector3D &tex = ( m_currentVertices.m_textureCoords[ 0 ][ idx ] );
|
||||||
|
|
||||||
|
ai_assert( index < m_currentMesh->mNumVertices );
|
||||||
|
m_currentMesh->mVertices[ index ].Set( pos.x, pos.y, pos.z );
|
||||||
|
m_currentMesh->mNormals[ index ].Set( normal.x, normal.y, normal.z );
|
||||||
|
m_currentMesh->mTextureCoords[0][ index ].Set( tex.x, tex.y, tex.z );
|
||||||
|
current.mIndices[ indices ] = index;
|
||||||
|
index++;
|
||||||
|
|
||||||
|
next = next->m_next;
|
||||||
|
}
|
||||||
|
vaList = vaList->m_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::copyMeshes( aiScene *pScene ) {
|
||||||
|
if( m_meshCache.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pScene->mNumMeshes = m_meshCache.size();
|
||||||
|
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
|
||||||
|
size_t i( 0 );
|
||||||
|
for( std::vector<aiMesh*>::iterator it = m_meshCache.begin(); it != m_meshCache.end(); it++ ) {
|
||||||
|
pScene->mMeshes[ i ] = *it;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::resolveReferences() {
|
||||||
|
if( m_unresolvedRefStack.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefInfo *currentRefInfo( NULL );
|
||||||
|
for( std::vector<RefInfo*>::iterator it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
||||||
|
currentRefInfo = *it;
|
||||||
|
if( NULL != currentRefInfo ) {
|
||||||
|
aiNode *node( currentRefInfo->m_node );
|
||||||
|
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
|
||||||
|
for( size_t i = 0; i < currentRefInfo->m_Names.size(); i++ ) {
|
||||||
|
const std::string &name(currentRefInfo->m_Names[ i ] );
|
||||||
|
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
|
||||||
|
if( m_mesh2refMap.end() != it ) {
|
||||||
|
unsigned int meshIdx = m_mesh2refMap[ name ];
|
||||||
|
node->mMeshes[ i ] = meshIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
|
||||||
|
// ToDo!
|
||||||
|
} else {
|
||||||
|
throw DeadlyImportError( "Unknown reference info to resolve." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::createNodeTree( aiScene *pScene ) {
|
||||||
|
if( NULL == m_root ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_root->m_children.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t i( 0 );
|
||||||
|
pScene->mRootNode->mNumChildren = m_root->m_children.size();
|
||||||
|
pScene->mRootNode->mChildren = new C_STRUCT aiNode*[ pScene->mRootNode->mNumChildren ];
|
||||||
|
for( ChildInfo::NodeList::iterator it = m_root->m_children.begin(); it != m_root->m_children.end(); it++ ) {
|
||||||
|
pScene->mRootNode->mChildren[ i ] = *it;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
||||||
|
ai_assert( NULL != pScene );
|
||||||
|
|
||||||
|
if( NULL != node ) {
|
||||||
|
ChildInfo *info( NULL );
|
||||||
|
if( m_nodeStack.empty() ) {
|
||||||
|
node->mParent = pScene->mRootNode;
|
||||||
|
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||||
|
if( m_nodeChildMap.end() == it ) {
|
||||||
|
info = new ChildInfo;
|
||||||
|
m_root = info;
|
||||||
|
m_nodeChildMap[ node->mParent ] = info;
|
||||||
|
} else {
|
||||||
|
info = it->second;
|
||||||
|
}
|
||||||
|
info->m_children.push_back( node );
|
||||||
|
} else {
|
||||||
|
aiNode *parent( m_nodeStack.back() );
|
||||||
|
ai_assert( NULL != parent );
|
||||||
|
node->mParent = parent;
|
||||||
|
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||||
|
if( m_nodeChildMap.end() == it ) {
|
||||||
|
info = new ChildInfo;
|
||||||
|
m_nodeChildMap[ node->mParent ] = info;
|
||||||
|
} else {
|
||||||
|
info = it->second;
|
||||||
|
}
|
||||||
|
info->m_children.push_back( node );
|
||||||
|
}
|
||||||
|
m_nodeStack.push_back( node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
aiNode *OpenGEXImporter::popNode() {
|
||||||
|
if( m_nodeStack.empty() ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiNode *node( top() );
|
||||||
|
m_nodeStack.pop_back();
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
aiNode *OpenGEXImporter::top() const {
|
||||||
|
if( m_nodeStack.empty() ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_nodeStack.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::clearNodeStack() {
|
||||||
|
m_nodeStack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // Namespace OpenGEX
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2014, 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_OPENGEX_IMPORTER_H
|
||||||
|
#define AI_OPENGEX_IMPORTER_H
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ODDLParser {
|
||||||
|
class DDLNode;
|
||||||
|
struct Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace OpenGEX {
|
||||||
|
|
||||||
|
struct MetricInfo {
|
||||||
|
enum Type {
|
||||||
|
Distance = 0,
|
||||||
|
Angle,
|
||||||
|
Time,
|
||||||
|
Up,
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string m_stringValue;
|
||||||
|
float m_floatValue;
|
||||||
|
int m_intValue;
|
||||||
|
|
||||||
|
MetricInfo()
|
||||||
|
: m_stringValue( "" )
|
||||||
|
, m_floatValue( 0.0f )
|
||||||
|
, m_intValue( -1 ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief This class is used to implement the OpenGEX importer
|
||||||
|
*
|
||||||
|
* See http://opengex.org/OpenGEX.pdf for spec.
|
||||||
|
*/
|
||||||
|
class OpenGEXImporter : public BaseImporter {
|
||||||
|
public:
|
||||||
|
/// The class constructor.
|
||||||
|
OpenGEXImporter();
|
||||||
|
|
||||||
|
/// The class destructor.
|
||||||
|
virtual ~OpenGEXImporter();
|
||||||
|
|
||||||
|
/// BaseImporter override.
|
||||||
|
virtual bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const;
|
||||||
|
|
||||||
|
/// BaseImporter override.
|
||||||
|
virtual void InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler );
|
||||||
|
|
||||||
|
/// BaseImporter override.
|
||||||
|
virtual const aiImporterDesc *GetInfo() const;
|
||||||
|
|
||||||
|
/// BaseImporter override.
|
||||||
|
virtual void SetupProperties( const Importer *pImp );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void handleNodes( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleObjectRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||||
|
void copyMeshes( aiScene *pScene );
|
||||||
|
void resolveReferences();
|
||||||
|
void pushNode( aiNode *node, aiScene *pScene );
|
||||||
|
aiNode *popNode();
|
||||||
|
aiNode *top() const;
|
||||||
|
void clearNodeStack();
|
||||||
|
void createNodeTree( aiScene *pScene );
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct VertexContainer {
|
||||||
|
size_t m_numVerts;
|
||||||
|
aiVector3D *m_vertices;
|
||||||
|
size_t m_numNormals;
|
||||||
|
aiVector3D *m_normals;
|
||||||
|
size_t m_numUVComps[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
|
||||||
|
aiVector3D *m_textureCoords[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
|
||||||
|
|
||||||
|
VertexContainer();
|
||||||
|
~VertexContainer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
VertexContainer( const VertexContainer & );
|
||||||
|
VertexContainer &operator = ( const VertexContainer & );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RefInfo {
|
||||||
|
enum Type {
|
||||||
|
MeshRef,
|
||||||
|
MaterialRef
|
||||||
|
};
|
||||||
|
|
||||||
|
aiNode *m_node;
|
||||||
|
Type m_type;
|
||||||
|
std::vector<std::string> m_Names;
|
||||||
|
|
||||||
|
RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
|
||||||
|
~RefInfo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefInfo( const RefInfo & );
|
||||||
|
RefInfo &operator = ( const RefInfo & );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChildInfo {
|
||||||
|
typedef std::list<aiNode*> NodeList;
|
||||||
|
std::list<aiNode*> m_children;
|
||||||
|
};
|
||||||
|
ChildInfo *m_root;
|
||||||
|
typedef std::map<aiNode*, ChildInfo*> NodeChildMap;
|
||||||
|
NodeChildMap m_nodeChildMap;
|
||||||
|
|
||||||
|
std::vector<aiMesh*> m_meshCache;
|
||||||
|
typedef std::map<std::string, size_t> ReferenceMap;
|
||||||
|
std::map<std::string, size_t> m_mesh2refMap;
|
||||||
|
|
||||||
|
ODDLParser::Context *m_ctx;
|
||||||
|
MetricInfo m_metrics[ MetricInfo::Max ];
|
||||||
|
aiNode *m_currentNode;
|
||||||
|
VertexContainer m_currentVertices;
|
||||||
|
aiMesh *m_currentMesh;
|
||||||
|
std::vector<aiNode*> m_nodeStack;
|
||||||
|
std::vector<RefInfo*> m_unresolvedRefStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Namespace OpenGEX
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||||
|
|
||||||
|
#endif // AI_OPENGEX_IMPORTER_H
|
|
@ -0,0 +1,265 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2014, 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_OPENGEXSTRUCTS_H_INC
|
||||||
|
#define AI_OPENGEXSTRUCTS_H_INC
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace OpenGEX {
|
||||||
|
|
||||||
|
struct Skin;
|
||||||
|
struct Object;
|
||||||
|
struct LightObject;
|
||||||
|
struct CameraObject;
|
||||||
|
struct Material;
|
||||||
|
struct BoneNode;
|
||||||
|
struct BoneCountArray;
|
||||||
|
struct BoneIndexArray;
|
||||||
|
struct BoneWeightArray;
|
||||||
|
|
||||||
|
struct Metric {
|
||||||
|
float m_distance;
|
||||||
|
float m_angle;
|
||||||
|
float m_time;
|
||||||
|
float m_up;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexArray {
|
||||||
|
std::string arrayAttrib;
|
||||||
|
unsigned int morphIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndexArray {
|
||||||
|
unsigned int materialIndex;
|
||||||
|
unsigned int restartIndex;
|
||||||
|
std::string frontFace;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mesh {
|
||||||
|
unsigned int meshLevel;
|
||||||
|
std::string meshPrimitive;
|
||||||
|
Skin *skinStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
std::string nodeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeometryNode {
|
||||||
|
bool visibleFlag[ 2 ];
|
||||||
|
bool shadowFlag[ 2 ];
|
||||||
|
bool motionBlurFlag[ 2 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LightNode {
|
||||||
|
bool shadowFlag[ 2 ];
|
||||||
|
const LightObject *lightObjectStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CameraNode {
|
||||||
|
const CameraObject *cameraObjectStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeometryObject {
|
||||||
|
Object *object;
|
||||||
|
bool visibleFlag;
|
||||||
|
bool shadowFlag;
|
||||||
|
bool motionBlurFlag;
|
||||||
|
std::map<std::string, Mesh*> meshMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LightObject {
|
||||||
|
Object *object;
|
||||||
|
std::string typeString;
|
||||||
|
bool shadowFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CameraObject {
|
||||||
|
float focalLength;
|
||||||
|
float nearDepth;
|
||||||
|
float farDepth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Matrix {
|
||||||
|
bool objectFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Transform {
|
||||||
|
Matrix *matrix;
|
||||||
|
int transformCount;
|
||||||
|
const float *transformArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Translation {
|
||||||
|
std::string translationKind;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Rotation {
|
||||||
|
std::string rotationKind;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scale {
|
||||||
|
std::string scaleKind;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Name {
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ObjectRef {
|
||||||
|
Object *targetStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaterialRef {
|
||||||
|
unsigned int materialIndex;
|
||||||
|
const Material *targetStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoneRefArray {
|
||||||
|
int boneCount;
|
||||||
|
const BoneNode **boneNodeArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoneCount {
|
||||||
|
int vertexCount;
|
||||||
|
const unsigned short *boneCountArray;
|
||||||
|
unsigned short *arrayStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoneIndex {
|
||||||
|
int boneIndexCount;
|
||||||
|
const unsigned short *boneIndexArray;
|
||||||
|
unsigned short *arrayStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct BoneWeight {
|
||||||
|
int boneWeightCount;
|
||||||
|
const float *boneWeightArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Skeleton {
|
||||||
|
const BoneRefArray *boneRefArrayStructure;
|
||||||
|
const Transform *transformStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Skin {
|
||||||
|
const Skeleton *skeletonStructure;
|
||||||
|
const BoneCountArray *boneCountArrayStructure;
|
||||||
|
const BoneIndexArray *boneIndexArrayStructure;
|
||||||
|
const BoneWeightArray *boneWeightArrayStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
bool twoSidedFlag;
|
||||||
|
const char *materialName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Attrib {
|
||||||
|
std::string attribString;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Param {
|
||||||
|
float param;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Color {
|
||||||
|
float color[ 4 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Texture {
|
||||||
|
std::string textureName;
|
||||||
|
unsigned int texcoordIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Atten {
|
||||||
|
std::string attenKind;
|
||||||
|
std::string curveType;
|
||||||
|
|
||||||
|
float beginParam;
|
||||||
|
float endParam;
|
||||||
|
|
||||||
|
float scaleParam;
|
||||||
|
float offsetParam;
|
||||||
|
|
||||||
|
float constantParam;
|
||||||
|
float linearParam;
|
||||||
|
float quadraticParam;
|
||||||
|
|
||||||
|
float powerParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Key {
|
||||||
|
std::string keyKind;
|
||||||
|
bool scalarFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Curve {
|
||||||
|
std::string curveType;
|
||||||
|
const Key *keyValueStructure;
|
||||||
|
const Key *keyControlStructure[ 2 ];
|
||||||
|
const Key *keyTensionStructure;
|
||||||
|
const Key *keyContinuityStructure;
|
||||||
|
const Key *keyBiasStructure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Animation {
|
||||||
|
int clipIndex;
|
||||||
|
bool beginFlag;
|
||||||
|
bool endFlag;
|
||||||
|
float beginTime;
|
||||||
|
float endTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpenGexDataDescription {
|
||||||
|
float distanceScale;
|
||||||
|
float angleScale;
|
||||||
|
float timeScale;
|
||||||
|
int upDirection;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Namespace OpenGEX
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_OPENGEXSTRUCTS_H_INC
|
|
@ -202,7 +202,12 @@ template <class char_t>
|
||||||
AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
|
AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
|
||||||
{
|
{
|
||||||
if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
|
if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
|
||||||
in += len+1;
|
if (in[len] != '\0') {
|
||||||
|
in += len+1;
|
||||||
|
} else {
|
||||||
|
// If EOF after the token make sure we don't go past end of buffer
|
||||||
|
in += len;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
|
||||||
void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
PlyExporter exporter(pFile, pScene);
|
PlyExporter exporter(pFile, pScene);
|
||||||
|
@ -69,7 +69,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
PlyExporter exporter(pFile, pScene, true);
|
PlyExporter exporter(pFile, pScene, true);
|
||||||
|
|
|
@ -68,6 +68,25 @@ static const aiImporterDesc desc = {
|
||||||
"ply"
|
"ply"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Internal stuff
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Checks that property index is within range
|
||||||
|
template <class T>
|
||||||
|
const T &GetProperty(const std::vector<T> &props, int idx)
|
||||||
|
{
|
||||||
|
if( static_cast< size_t >( idx ) >= props.size() ) {
|
||||||
|
throw DeadlyImportError( "Invalid .ply file: Property index is out of range." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return props[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
PLYImporter::PLYImporter()
|
PLYImporter::PLYImporter()
|
||||||
|
@ -435,13 +454,13 @@ void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
|
||||||
if (0xFFFFFFFF != aiPositions[0])
|
if (0xFFFFFFFF != aiPositions[0])
|
||||||
{
|
{
|
||||||
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
|
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
|
||||||
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
|
GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[1])
|
if (0xFFFFFFFF != aiPositions[1])
|
||||||
{
|
{
|
||||||
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
|
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
|
||||||
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
|
GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
|
||||||
}
|
}
|
||||||
// and add them to our nice list
|
// and add them to our nice list
|
||||||
pvOut->push_back(vOut);
|
pvOut->push_back(vOut);
|
||||||
|
@ -545,19 +564,19 @@ void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
|
||||||
if (0xFFFFFFFF != aiPositions[0])
|
if (0xFFFFFFFF != aiPositions[0])
|
||||||
{
|
{
|
||||||
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
|
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
|
||||||
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
|
GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[1])
|
if (0xFFFFFFFF != aiPositions[1])
|
||||||
{
|
{
|
||||||
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
|
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
|
||||||
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
|
GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[2])
|
if (0xFFFFFFFF != aiPositions[2])
|
||||||
{
|
{
|
||||||
vOut.z = PLY::PropertyInstance::ConvertTo<float>(
|
vOut.z = PLY::PropertyInstance::ConvertTo<float>(
|
||||||
(*i).alProperties[aiPositions[2]].avList.front(),aiTypes[2]);
|
GetProperty((*i).alProperties, aiPositions[2]).avList.front(),aiTypes[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and add them to our nice list
|
// and add them to our nice list
|
||||||
|
@ -663,28 +682,28 @@ void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[0])
|
if (0xFFFFFFFF != aiPositions[0])
|
||||||
{
|
{
|
||||||
vOut.r = NormalizeColorValue((*i).alProperties[
|
vOut.r = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||||
aiPositions[0]].avList.front(),aiTypes[0]);
|
aiPositions[0]).avList.front(),aiTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[1])
|
if (0xFFFFFFFF != aiPositions[1])
|
||||||
{
|
{
|
||||||
vOut.g = NormalizeColorValue((*i).alProperties[
|
vOut.g = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||||
aiPositions[1]].avList.front(),aiTypes[1]);
|
aiPositions[1]).avList.front(),aiTypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[2])
|
if (0xFFFFFFFF != aiPositions[2])
|
||||||
{
|
{
|
||||||
vOut.b = NormalizeColorValue((*i).alProperties[
|
vOut.b = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||||
aiPositions[2]].avList.front(),aiTypes[2]);
|
aiPositions[2]).avList.front(),aiTypes[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume 1.0 for the alpha channel ifit is not set
|
// assume 1.0 for the alpha channel ifit is not set
|
||||||
if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
|
if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vOut.a = NormalizeColorValue((*i).alProperties[
|
vOut.a = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||||
aiPositions[3]].avList.front(),aiTypes[3]);
|
aiPositions[3]).avList.front(),aiTypes[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and add them to our nice list
|
// and add them to our nice list
|
||||||
|
@ -777,11 +796,11 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
|
||||||
// parse the list of vertex indices
|
// parse the list of vertex indices
|
||||||
if (0xFFFFFFFF != iProperty)
|
if (0xFFFFFFFF != iProperty)
|
||||||
{
|
{
|
||||||
const unsigned int iNum = (unsigned int)(*i).alProperties[iProperty].avList.size();
|
const unsigned int iNum = (unsigned int)GetProperty((*i).alProperties, iProperty).avList.size();
|
||||||
sFace.mIndices.resize(iNum);
|
sFace.mIndices.resize(iNum);
|
||||||
|
|
||||||
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
|
||||||
(*i).alProperties[iProperty].avList.begin();
|
GetProperty((*i).alProperties, iProperty).avList.begin();
|
||||||
|
|
||||||
for (unsigned int a = 0; a < iNum;++a,++p)
|
for (unsigned int a = 0; a < iNum;++a,++p)
|
||||||
{
|
{
|
||||||
|
@ -793,7 +812,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
|
||||||
if (0xFFFFFFFF != iMaterialIndex)
|
if (0xFFFFFFFF != iMaterialIndex)
|
||||||
{
|
{
|
||||||
sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
||||||
(*i).alProperties[iMaterialIndex].avList.front(),eType2);
|
GetProperty((*i).alProperties, iMaterialIndex).avList.front(),eType2);
|
||||||
}
|
}
|
||||||
pvOut->push_back(sFace);
|
pvOut->push_back(sFace);
|
||||||
}
|
}
|
||||||
|
@ -804,7 +823,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
|
||||||
// a value of -1 indicates a restart of the strip
|
// a value of -1 indicates a restart of the strip
|
||||||
bool flip = false;
|
bool flip = false;
|
||||||
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
|
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
|
||||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
|
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty((*i).alProperties, iProperty).avList;
|
||||||
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
|
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
|
||||||
|
|
||||||
int aiTable[2] = {-1,-1};
|
int aiTable[2] = {-1,-1};
|
||||||
|
@ -855,30 +874,30 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avL
|
||||||
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
|
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clrOut->r = NormalizeColorValue(avList[
|
clrOut->r = NormalizeColorValue(GetProperty(avList,
|
||||||
aiPositions[0]].avList.front(),aiTypes[0]);
|
aiPositions[0]).avList.front(),aiTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
|
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clrOut->g = NormalizeColorValue(avList[
|
clrOut->g = NormalizeColorValue(GetProperty(avList,
|
||||||
aiPositions[1]].avList.front(),aiTypes[1]);
|
aiPositions[1]).avList.front(),aiTypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
|
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clrOut->b = NormalizeColorValue(avList[
|
clrOut->b = NormalizeColorValue(GetProperty(avList,
|
||||||
aiPositions[2]].avList.front(),aiTypes[2]);
|
aiPositions[2]).avList.front(),aiTypes[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume 1.0 for the alpha channel ifit is not set
|
// assume 1.0 for the alpha channel ifit is not set
|
||||||
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
|
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clrOut->a = NormalizeColorValue(avList[
|
clrOut->a = NormalizeColorValue(GetProperty(avList,
|
||||||
aiPositions[3]].avList.front(),aiTypes[3]);
|
aiPositions[3]).avList.front(),aiTypes[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,7 +1048,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
|
||||||
// handle phong power and shading mode
|
// handle phong power and shading mode
|
||||||
int iMode;
|
int iMode;
|
||||||
if (0xFFFFFFFF != iPhong) {
|
if (0xFFFFFFFF != iPhong) {
|
||||||
float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong);
|
float fSpec = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),ePhong);
|
||||||
|
|
||||||
// if shininess is 0 (and the pow() calculation would therefore always
|
// if shininess is 0 (and the pow() calculation would therefore always
|
||||||
// become 1, not depending on the angle), use gouraud lighting
|
// become 1, not depending on the angle), use gouraud lighting
|
||||||
|
@ -1047,7 +1066,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
|
||||||
|
|
||||||
// handle opacity
|
// handle opacity
|
||||||
if (0xFFFFFFFF != iOpacity) {
|
if (0xFFFFFFFF != iOpacity) {
|
||||||
float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity);
|
float fOpacity = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),eOpacity);
|
||||||
pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
|
pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
STLExporter exporter(pFile, pScene);
|
STLExporter exporter(pFile, pScene);
|
||||||
|
@ -68,7 +68,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
STLExporter exporter(pFile, pScene, true);
|
STLExporter exporter(pFile, pScene, true);
|
||||||
|
|
|
@ -1026,7 +1026,9 @@ void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
|
||||||
dest->mFlags = src->mFlags;
|
dest->mFlags = src->mFlags;
|
||||||
|
|
||||||
// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
|
// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
|
||||||
ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
|
if (dest->mPrivate != NULL) {
|
||||||
|
ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -289,6 +289,8 @@ void CatmullClarkSubdivider::InternSubdivide (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// we want edges to go away before the recursive calls so begin a new scope
|
||||||
EdgeMap edges;
|
EdgeMap edges;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
@ -571,6 +573,7 @@ void CatmullClarkSubdivider::InternSubdivide (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // end of scope for edges, freeing its memory
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// 7. Apply the next subdivision step.
|
// 7. Apply the next subdivision step.
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace Assimp
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
std::string path = "";
|
std::string path = "";
|
||||||
std::string file = pFile;
|
std::string file = pFile;
|
||||||
|
@ -85,13 +85,19 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create/copy Properties
|
||||||
|
ExportProperties props(*pProperties);
|
||||||
|
|
||||||
|
// set standard properties if not set
|
||||||
|
if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
|
||||||
|
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file);
|
XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
|
||||||
|
|
||||||
// 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) {
|
if(outfile == NULL) {
|
||||||
throw DeadlyExportError("could not open output .dae file: " + std::string(pFile));
|
throw DeadlyExportError("could not open output .x 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.
|
||||||
|
@ -103,7 +109,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor for a specific scene to export
|
// Constructor for a specific scene to export
|
||||||
XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
|
XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties) : mIOSystem(pIOSystem), mPath(path), mFile(file), mProperties(pProperties)
|
||||||
{
|
{
|
||||||
// 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
|
||||||
mOutput.imbue( std::locale("C") );
|
mOutput.imbue( std::locale("C") );
|
||||||
|
@ -133,7 +139,7 @@ void XFileExporter::WriteFile()
|
||||||
{
|
{
|
||||||
// note, that all realnumber values must be comma separated in x files
|
// note, that all realnumber values must be comma separated in x files
|
||||||
mOutput.setf(std::ios::fixed);
|
mOutput.setf(std::ios::fixed);
|
||||||
mOutput.precision(6); // precission for float
|
mOutput.precision(16); // precission for double
|
||||||
|
|
||||||
// entry of writing the file
|
// entry of writing the file
|
||||||
WriteHeader();
|
WriteHeader();
|
||||||
|
@ -155,7 +161,10 @@ void XFileExporter::WriteFile()
|
||||||
// Writes the asset header
|
// Writes the asset header
|
||||||
void XFileExporter::WriteHeader()
|
void XFileExporter::WriteHeader()
|
||||||
{
|
{
|
||||||
mOutput << startstr << "xof 0303txt 0032" << endstr;
|
if (mProperties->GetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT) == true)
|
||||||
|
mOutput << startstr << "xof 0303txt 0064" << endstr;
|
||||||
|
else
|
||||||
|
mOutput << startstr << "xof 0303txt 0032" << endstr;
|
||||||
mOutput << endstr;
|
mOutput << endstr;
|
||||||
mOutput << startstr << "template Frame {" << endstr;
|
mOutput << startstr << "template Frame {" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
@ -305,7 +314,7 @@ void XFileExporter::WriteNode( aiNode* pNode)
|
||||||
ss << "Node_" << pNode;
|
ss << "Node_" << pNode;
|
||||||
pNode->mName.Set(ss.str());
|
pNode->mName.Set(ss.str());
|
||||||
}
|
}
|
||||||
mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << endstr;
|
mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
|
||||||
|
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
|
@ -325,9 +334,9 @@ void XFileExporter::WriteNode( aiNode* pNode)
|
||||||
mOutput << startstr << "}" << endstr << endstr;
|
mOutput << startstr << "}" << endstr << endstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFileExporter::WriteMesh(const aiMesh* mesh)
|
void XFileExporter::WriteMesh(aiMesh* mesh)
|
||||||
{
|
{
|
||||||
mOutput << startstr << "Mesh " << mesh->mName.C_Str() << "_mShape" << " {" << endstr;
|
mOutput << startstr << "Mesh " << toXFileString(mesh->mName) << "_mShape" << " {" << endstr;
|
||||||
|
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
|
@ -503,6 +512,16 @@ void XFileExporter::WriteMesh(const aiMesh* mesh)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string XFileExporter::toXFileString(aiString &name)
|
||||||
|
{
|
||||||
|
std::string str = std::string(name.C_Str());
|
||||||
|
std::replace(str.begin(), str.end(), '<', '_');
|
||||||
|
std::replace(str.begin(), str.end(), '>', '_');
|
||||||
|
std::replace(str.begin(), str.end(), '{', '_');
|
||||||
|
std::replace(str.begin(), str.end(), '}', '_');
|
||||||
|
std::replace(str.begin(), str.end(), '$', '_');
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
void XFileExporter::writePath(aiString path)
|
void XFileExporter::writePath(aiString path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,7 @@ class XFileExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// Constructor for a specific scene to export
|
||||||
XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
|
XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~XFileExporter();
|
virtual ~XFileExporter();
|
||||||
|
@ -85,7 +85,7 @@ protected:
|
||||||
void WriteNode( aiNode* pNode );
|
void WriteNode( aiNode* pNode );
|
||||||
|
|
||||||
/// write a mesh entry of the scene
|
/// write a mesh entry of the scene
|
||||||
void WriteMesh(const aiMesh* mesh);
|
void WriteMesh( aiMesh* mesh);
|
||||||
|
|
||||||
/// Enters a new xml element, which increases the indentation
|
/// Enters a new xml element, which increases the indentation
|
||||||
void PushTag() { startstr.append( " "); }
|
void PushTag() { startstr.append( " "); }
|
||||||
|
@ -99,6 +99,12 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// normalize the name to be accepted by xfile readers
|
||||||
|
std::string toXFileString(aiString &name);
|
||||||
|
|
||||||
|
/// hold the properties pointer
|
||||||
|
const ExportProperties* mProperties;
|
||||||
|
|
||||||
/// write a path
|
/// write a path
|
||||||
void writePath(aiString path);
|
void writePath(aiString path);
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ static const aiImporterDesc desc = {
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
aiImporterFlags_SupportTextFlavour,
|
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -435,6 +435,12 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIX: since we used std::multimap<> to keep meshes by id, mesh order now depends on the behaviour
|
||||||
|
// of the multimap implementation with respect to the ordering of entries with same values.
|
||||||
|
// C++11 gives the guarantee that it uses insertion order, before it is implementation-specific.
|
||||||
|
// Sort by material id to always guarantee a deterministic result.
|
||||||
|
std::sort(meshes.begin(), meshes.end(), SortMeshByMaterialId(scope));
|
||||||
|
|
||||||
// link meshes to node
|
// link meshes to node
|
||||||
nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||||
if (nd->mNumMeshes) {
|
if (nd->mNumMeshes) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
struct TempScope
|
struct TempScope
|
||||||
{
|
{
|
||||||
TempScope()
|
TempScope()
|
||||||
|
@ -129,6 +130,16 @@ private:
|
||||||
aiLight* light;
|
aiLight* light;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SortMeshByMaterialId {
|
||||||
|
SortMeshByMaterialId(const TempScope& scope) : scope(scope) {}
|
||||||
|
bool operator()(unsigned int a, unsigned int b) const {
|
||||||
|
return scope.meshes_linear[a]->mMaterialIndex < scope.meshes_linear[b]->mMaterialIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TempScope& scope;
|
||||||
|
};
|
||||||
|
|
||||||
struct TempMesh
|
struct TempMesh
|
||||||
{
|
{
|
||||||
std::map<unsigned int, aiVector3D> points;
|
std::map<unsigned int, aiVector3D> points;
|
||||||
|
|
|
@ -223,6 +223,23 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------
|
||||||
|
// signed variant of strtoul10_64
|
||||||
|
// ------------------------------------------------------------------------------------
|
||||||
|
inline int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0)
|
||||||
|
{
|
||||||
|
bool inv = (*in == '-');
|
||||||
|
if (inv || *in == '+')
|
||||||
|
++in;
|
||||||
|
|
||||||
|
int64_t value = strtoul10_64(in, out, max_inout);
|
||||||
|
if (inv) {
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Number of relevant decimals for floating-point parsing.
|
// Number of relevant decimals for floating-point parsing.
|
||||||
#define AI_FAST_ATOF_RELAVANT_DECIMALS 15
|
#define AI_FAST_ATOF_RELAVANT_DECIMALS 15
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
|
||||||
|
PROJECT( OpenDDL-Parser )
|
||||||
|
SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
|
||||||
|
SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
|
||||||
|
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
|
||||||
|
SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} )
|
||||||
|
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
|
||||||
|
|
||||||
|
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
find_package(Threads)
|
||||||
|
else()
|
||||||
|
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||||
|
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||||
|
add_definitions( -D_VARIADIC_MAX=10 )
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
./
|
||||||
|
include/
|
||||||
|
contrib/gtest-1.7.0/include
|
||||||
|
contrib/gtest-1.7.0/
|
||||||
|
)
|
||||||
|
|
||||||
|
link_directories(
|
||||||
|
./
|
||||||
|
)
|
||||||
|
|
||||||
|
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||||
|
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||||
|
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
||||||
|
|
||||||
|
if( WIN32 AND NOT CYGWIN )
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4
|
||||||
|
if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" )
|
||||||
|
string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
|
||||||
|
else()
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
|
||||||
|
endif()
|
||||||
|
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
# Update if necessary
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x")
|
||||||
|
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
SET ( openddl_parser_src
|
||||||
|
code/OpenDDLParser.cpp
|
||||||
|
code/DDLNode.cpp
|
||||||
|
code/Value.cpp
|
||||||
|
include/openddlparser/OpenDDLParser.h
|
||||||
|
include/openddlparser/OpenDDLParserUtils.h
|
||||||
|
include/openddlparser/OpenDDLCommon.h
|
||||||
|
include/openddlparser/DDLNode.h
|
||||||
|
include/openddlparser/Value.h
|
||||||
|
README.md
|
||||||
|
)
|
||||||
|
|
||||||
|
SOURCE_GROUP( code FILES ${openddl_parser_src} )
|
||||||
|
|
||||||
|
ADD_LIBRARY( openddl_parser SHARED
|
||||||
|
${openddl_parser_src}
|
||||||
|
)
|
|
@ -0,0 +1,111 @@
|
||||||
|
The OpenDDL-Parser
|
||||||
|
==================
|
||||||
|
|
||||||
|
A simple and fast OpenDDL Parser
|
||||||
|
Current build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
|
||||||
|
|
||||||
|
Get the source code
|
||||||
|
===================
|
||||||
|
You can get the code from our git repository, which is located at GitHub. You can clone the repository like:
|
||||||
|
|
||||||
|
> git clone https://github.com/kimkulling/openddl-parser.git
|
||||||
|
|
||||||
|
Build from repo
|
||||||
|
===============
|
||||||
|
To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler toolchain is installed on your machine.
|
||||||
|
After installing it you can open a console and type:
|
||||||
|
|
||||||
|
> cmake CMakeLists.txt
|
||||||
|
|
||||||
|
This command will generate a build environment for your installed build enrironment ( for Visual Studio the project files will be generated, for gcc the makefiles will be generated ).
|
||||||
|
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
|
||||||
|
|
||||||
|
> make
|
||||||
|
|
||||||
|
and that's all.
|
||||||
|
|
||||||
|
Use the library
|
||||||
|
===============
|
||||||
|
To use the OpenDDL-parser you need to build the lib first. Now add the
|
||||||
|
> <Repo-folder>/include
|
||||||
|
|
||||||
|
to your include-path and the
|
||||||
|
|
||||||
|
> <Repo-folder>/lib
|
||||||
|
|
||||||
|
to your lib-folder. Link the openddl.lib to your application.
|
||||||
|
|
||||||
|
Here is a small example how to use the lib:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <openddlparser/OpenDDLParser.h>
|
||||||
|
|
||||||
|
USE_ODDLPARSER_NS;
|
||||||
|
|
||||||
|
int main( int argc, char *argv[] ) {
|
||||||
|
if( argc < 3 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *filename( nullptr );
|
||||||
|
if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) {
|
||||||
|
filename = argv[ 2 ];
|
||||||
|
}
|
||||||
|
std::cout << "file to import: " << filename << std::endl;
|
||||||
|
if( nullptr == filename ) {
|
||||||
|
std::cerr << "Invalid filename." << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fileStream = fopen( filename, "r+" );
|
||||||
|
if( NULL == filename ) {
|
||||||
|
std::cerr << "Cannot open file " << filename << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// obtain file size:
|
||||||
|
fseek( fileStream, 0, SEEK_END );
|
||||||
|
const size_t size( ftell( fileStream ) );
|
||||||
|
rewind( fileStream );
|
||||||
|
if( size > 0 ) {
|
||||||
|
char *buffer = new char[ size ];
|
||||||
|
const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) );
|
||||||
|
assert( readSize == size );
|
||||||
|
OpenDDLParser theParser;
|
||||||
|
theParser.setBuffer( buffer, size );
|
||||||
|
const bool result( theParser.parse() );
|
||||||
|
if( !result ) {
|
||||||
|
std::cerr << "Error while parsing file " << filename << "." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
How to access the imported data
|
||||||
|
===============================
|
||||||
|
The data is organized as a tree. You can get the root tree with the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
OpenDDLParser theParser;
|
||||||
|
theParser.setBuffer( buffer, size );
|
||||||
|
const bool result( theParser.parse() );
|
||||||
|
if ( result ) {
|
||||||
|
DDLNode *root = theParser.getRoot();
|
||||||
|
|
||||||
|
DDLNode::DllNodeList childs = root->getChildNodeList();
|
||||||
|
for ( size_t i=0; i<childs.size(); i++ ) {
|
||||||
|
DDLNode *child = childs[ i ];
|
||||||
|
Property *prop = child->getProperty(); // to get properties
|
||||||
|
std:.string type = child->getType(); // to get the node type
|
||||||
|
Value *values = child->getValue(); // to get the data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The instance called root contains the data.
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#include <openddlparser/DDLNode.h>
|
||||||
|
#include <openddlparser/OpenDDLParser.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
DDLNode::DllNodeList DDLNode::s_allocatedNodes;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
static void releaseDataType( T *ptr ) {
|
||||||
|
if( ddl_nullptr == ptr ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
T *current( ddl_nullptr );
|
||||||
|
while( ptr ) {
|
||||||
|
current = ptr;
|
||||||
|
ptr = ptr->m_next;
|
||||||
|
delete current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void releaseReferencedNames( Reference *ref ) {
|
||||||
|
if( ddl_nullptr == ref ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ref->m_referencedName ) {
|
||||||
|
for( size_t i = 0; i < ref->m_numRefs; i++ ) {
|
||||||
|
delete ref->m_referencedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent )
|
||||||
|
: m_type( type )
|
||||||
|
, m_name( name )
|
||||||
|
, m_parent( parent )
|
||||||
|
, m_children()
|
||||||
|
, m_properties( ddl_nullptr )
|
||||||
|
, m_value( ddl_nullptr )
|
||||||
|
, m_dtArrayList( ddl_nullptr )
|
||||||
|
, m_references( ddl_nullptr )
|
||||||
|
, m_idx( idx ) {
|
||||||
|
if( m_parent ) {
|
||||||
|
m_parent->m_children.push_back( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode::~DDLNode() {
|
||||||
|
releaseDataType<Property>( m_properties );
|
||||||
|
releaseDataType<Value>( m_value );
|
||||||
|
releaseReferencedNames( m_references );
|
||||||
|
|
||||||
|
delete m_dtArrayList;
|
||||||
|
m_dtArrayList = ddl_nullptr;
|
||||||
|
if( s_allocatedNodes[ m_idx ] == this ) {
|
||||||
|
s_allocatedNodes[ m_idx ] = ddl_nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::attachParent( DDLNode *parent ) {
|
||||||
|
if( m_parent == parent ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parent = parent;
|
||||||
|
if( ddl_nullptr != m_parent ) {
|
||||||
|
m_parent->m_children.push_back( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::detachParent() {
|
||||||
|
if( m_parent ) {
|
||||||
|
std::vector<DDLNode*>::iterator it;
|
||||||
|
it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
||||||
|
if( m_parent->m_children.end() != it ) {
|
||||||
|
m_parent->m_children.erase( it );
|
||||||
|
}
|
||||||
|
m_parent = ddl_nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *DDLNode::getParent() const {
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DDLNode::DllNodeList &DDLNode::getChildNodeList() const {
|
||||||
|
return m_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::setType( const std::string &type ) {
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &DDLNode::getType() const {
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DDLNode::setName( const std::string &name ) {
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &DDLNode::getName() const {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::setProperties( Property *prop ) {
|
||||||
|
m_properties = prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property *DDLNode::getProperties() const {
|
||||||
|
return m_properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::setValue( Value *val ) {
|
||||||
|
m_value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *DDLNode::getValue() const {
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) {
|
||||||
|
m_dtArrayList = dtArrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataArrayList *DDLNode::getDataArrayList() const {
|
||||||
|
return m_dtArrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::setReferences( Reference *refs ) {
|
||||||
|
m_references = refs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference *DDLNode::getReferences() const {
|
||||||
|
return m_references;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
|
||||||
|
const size_t idx( s_allocatedNodes.size() );
|
||||||
|
DDLNode *node = new DDLNode( type, name, idx, parent );
|
||||||
|
s_allocatedNodes.push_back( node );
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDLNode::releaseNodes() {
|
||||||
|
if( s_allocatedNodes.size() > 0 ) {
|
||||||
|
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
||||||
|
if( *it ) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_allocatedNodes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
|
@ -0,0 +1,911 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#include <openddlparser/OpenDDLParser.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#define DEBUG_HEADER_NAME
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
static const char *Version = "0.1.0";
|
||||||
|
|
||||||
|
namespace Grammar {
|
||||||
|
static const char *OpenBracketToken = "{";
|
||||||
|
static const char *CloseBracketToken = "}";
|
||||||
|
static const char *OpenPropertyToken = "(";
|
||||||
|
static const char *ClosePropertyToken = ")";
|
||||||
|
static const char *BoolTrue = "true";
|
||||||
|
static const char *BoolFalse = "false";
|
||||||
|
static const char *RefToken = "ref";
|
||||||
|
static const char *CommaSeparator = ",";
|
||||||
|
|
||||||
|
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
||||||
|
"bool",
|
||||||
|
"int8",
|
||||||
|
"int16",
|
||||||
|
"int32",
|
||||||
|
"int64",
|
||||||
|
"unsigned_int8",
|
||||||
|
"unsigned_int16",
|
||||||
|
"unsigned_int32",
|
||||||
|
"unsigned_int64",
|
||||||
|
"half",
|
||||||
|
"float",
|
||||||
|
"double",
|
||||||
|
"string",
|
||||||
|
"ref"
|
||||||
|
};
|
||||||
|
} // Namespace Grammar
|
||||||
|
|
||||||
|
|
||||||
|
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl;
|
||||||
|
callback( ddl_error_msg, stream.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isIntegerType( Value::ValueType integerType ) {
|
||||||
|
if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
|
||||||
|
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) {
|
||||||
|
if( ddl_nullptr == id || ddl_nullptr == parser ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string type( id->m_buffer );
|
||||||
|
DDLNode *parent( parser->top() );
|
||||||
|
DDLNode *node = DDLNode::create( type, "", parent );
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void logMessage( LogSeverity severity, const std::string &msg ) {
|
||||||
|
std::string log;
|
||||||
|
if( ddl_debug_msg == severity ) {
|
||||||
|
log += "Debug:";
|
||||||
|
} else if( ddl_info_msg == severity ) {
|
||||||
|
log += "Info :";
|
||||||
|
} else if( ddl_warn_msg == severity ) {
|
||||||
|
log += "Warn :";
|
||||||
|
} else if( ddl_error_msg == severity ) {
|
||||||
|
log += "Error:";
|
||||||
|
} else {
|
||||||
|
log += "None :";
|
||||||
|
}
|
||||||
|
|
||||||
|
log += msg;
|
||||||
|
std::cout << log;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDDLParser::OpenDDLParser()
|
||||||
|
: m_logCallback( logMessage )
|
||||||
|
, m_buffer()
|
||||||
|
, m_stack()
|
||||||
|
, m_context( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDDLParser::OpenDDLParser( char *buffer, size_t len )
|
||||||
|
: m_logCallback( &logMessage )
|
||||||
|
, m_buffer()
|
||||||
|
, m_context( ddl_nullptr ) {
|
||||||
|
if( 0 != len ) {
|
||||||
|
setBuffer( buffer, len );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDDLParser::~OpenDDLParser() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::setLogCallback( logCallback callback ) {
|
||||||
|
if( ddl_nullptr != callback ) {
|
||||||
|
// install user-specific log callback
|
||||||
|
m_logCallback = callback;
|
||||||
|
} else {
|
||||||
|
// install default log callback
|
||||||
|
m_logCallback = &logMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
|
||||||
|
return m_logCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::setBuffer( char *buffer, size_t len ) {
|
||||||
|
clear();
|
||||||
|
if( 0 == len ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer.resize( len );
|
||||||
|
::memcpy(&m_buffer[ 0 ], buffer, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::setBuffer( const std::vector<char> &buffer ) {
|
||||||
|
clear();
|
||||||
|
m_buffer.resize( buffer.size() );
|
||||||
|
std::copy( buffer.begin(), buffer.end(), m_buffer.begin() );
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *OpenDDLParser::getBuffer() const {
|
||||||
|
if( m_buffer.empty() ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &m_buffer[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t OpenDDLParser::getBufferSize() const {
|
||||||
|
return m_buffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::clear() {
|
||||||
|
m_buffer.resize( 0 );
|
||||||
|
if( m_context ) {
|
||||||
|
m_context->m_root = ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode::releaseNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenDDLParser::parse() {
|
||||||
|
if( m_buffer.empty() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizeBuffer( m_buffer );
|
||||||
|
|
||||||
|
std::cout << &m_buffer[0] << std::endl;
|
||||||
|
|
||||||
|
m_context = new Context;
|
||||||
|
m_context->m_root = DDLNode::create( "root", "", ddl_nullptr );
|
||||||
|
pushNode( m_context->m_root );
|
||||||
|
|
||||||
|
// do the main parsing
|
||||||
|
char *current( &m_buffer[ 0 ] );
|
||||||
|
char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
|
||||||
|
size_t pos( current - &m_buffer[ 0 ] );
|
||||||
|
while( pos < m_buffer.size() ) {
|
||||||
|
current = parseNextNode( current, end );
|
||||||
|
pos = current - &m_buffer[ 0 ];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
|
||||||
|
in = parseHeader( in, end );
|
||||||
|
in = parseStructure( in, end );
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpId( Identifier *id ) {
|
||||||
|
if( ddl_nullptr != id ) {
|
||||||
|
std::cout << id->m_buffer << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier *id( ddl_nullptr );
|
||||||
|
in = OpenDDLParser::parseIdentifier( in, end, &id );
|
||||||
|
|
||||||
|
#ifdef DEBUG_HEADER_NAME
|
||||||
|
dumpId( id );
|
||||||
|
#endif // DEBUG_HEADER_NAME
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
Property *first( ddl_nullptr );
|
||||||
|
if( ddl_nullptr != id ) {
|
||||||
|
if( *in == '(' ) {
|
||||||
|
in++;
|
||||||
|
Property *prop( ddl_nullptr ), *prev( ddl_nullptr );
|
||||||
|
while( *in != ')' && in != end ) {
|
||||||
|
in = OpenDDLParser::parseProperty( in, end, &prop );
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
|
||||||
|
if( *in != ',' && *in != ')' ) {
|
||||||
|
logInvalidTokenError( in, ")", m_logCallback );
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ddl_nullptr != prop && *in != ',' ) {
|
||||||
|
if( ddl_nullptr == first ) {
|
||||||
|
first = prop;
|
||||||
|
}
|
||||||
|
if( ddl_nullptr != prev ) {
|
||||||
|
prev->m_next = prop;
|
||||||
|
}
|
||||||
|
prev = prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the node
|
||||||
|
DDLNode *node( createDDLNode( id, this ) );
|
||||||
|
if( ddl_nullptr != node ) {
|
||||||
|
pushNode( node );
|
||||||
|
} else {
|
||||||
|
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the properties
|
||||||
|
if( ddl_nullptr != first ) {
|
||||||
|
node->setProperties( first );
|
||||||
|
}
|
||||||
|
|
||||||
|
Name *name( ddl_nullptr );
|
||||||
|
in = OpenDDLParser::parseName( in, end, &name );
|
||||||
|
if( ddl_nullptr != name ) {
|
||||||
|
const std::string nodeName( name->m_id->m_buffer );
|
||||||
|
node->setName( nodeName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool error( false );
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in == '{' ) {
|
||||||
|
// loop over all children ( data and nodes )
|
||||||
|
do {
|
||||||
|
in = parseStructureBody( in, end, error );
|
||||||
|
} while ( *in != '}' );
|
||||||
|
in++;
|
||||||
|
} else {
|
||||||
|
in++;
|
||||||
|
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
||||||
|
error = true;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
|
||||||
|
// pop node from stack after successful parsing
|
||||||
|
if( !error ) {
|
||||||
|
popNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setNodeValues( DDLNode *currentNode, Value *values ) {
|
||||||
|
if( ddl_nullptr != values ){
|
||||||
|
if( ddl_nullptr != currentNode ) {
|
||||||
|
currentNode->setValue( values );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setNodeReferences( DDLNode *currentNode, Reference *refs ) {
|
||||||
|
if( ddl_nullptr != refs ) {
|
||||||
|
if( ddl_nullptr != currentNode ) {
|
||||||
|
currentNode->setReferences( refs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) {
|
||||||
|
if( ddl_nullptr != dtArrayList ) {
|
||||||
|
if( ddl_nullptr != currentNode ) {
|
||||||
|
currentNode->setDataArrayList( dtArrayList );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
||||||
|
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
Value::ValueType type( Value::ddl_none );
|
||||||
|
size_t arrayLen( 0 );
|
||||||
|
in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
|
||||||
|
if( Value::ddl_none != type ) {
|
||||||
|
// parse a primitive data type
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in == '{' ) {
|
||||||
|
Reference *refs( ddl_nullptr );
|
||||||
|
DataArrayList *dtArrayList( ddl_nullptr );
|
||||||
|
Value *values( ddl_nullptr );
|
||||||
|
if( 1 == arrayLen ) {
|
||||||
|
size_t numRefs( 0 ), numValues( 0 );
|
||||||
|
in = parseDataList( in, end, &values, numValues, &refs, numRefs );
|
||||||
|
setNodeValues( top(), values );
|
||||||
|
setNodeReferences( top(), refs );
|
||||||
|
} else if( arrayLen > 1 ) {
|
||||||
|
in = parseDataArrayList( in, end, &dtArrayList );
|
||||||
|
setNodeDataArrayList( top(), dtArrayList );
|
||||||
|
} else {
|
||||||
|
std::cerr << "0 for array is invalid." << std::endl;
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in != '}' ) {
|
||||||
|
logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
|
||||||
|
} else {
|
||||||
|
//in++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// parse a complex data type
|
||||||
|
in = parseNextNode( in, end );
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::pushNode( DDLNode *node ) {
|
||||||
|
if( ddl_nullptr == node ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stack.push_back( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *OpenDDLParser::popNode() {
|
||||||
|
if( m_stack.empty() ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *topNode( top() );
|
||||||
|
m_stack.pop_back();
|
||||||
|
|
||||||
|
return topNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *OpenDDLParser::top() {
|
||||||
|
if( m_stack.empty() ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *top( m_stack.back() );
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLNode *OpenDDLParser::getRoot() const {
|
||||||
|
if( ddl_nullptr == m_context ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_context->m_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *OpenDDLParser::getContext() const {
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
|
||||||
|
if( buffer.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> newBuffer;
|
||||||
|
const size_t len( buffer.size() );
|
||||||
|
char *end( &buffer[ len-1 ] + 1 );
|
||||||
|
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
|
||||||
|
char *c( &buffer[readIdx] );
|
||||||
|
// check for a comment
|
||||||
|
if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
|
||||||
|
newBuffer.push_back( buffer[ readIdx ] );
|
||||||
|
} else {
|
||||||
|
if( isComment<char>( c, end ) ) {
|
||||||
|
readIdx++;
|
||||||
|
// skip the comment and the rest of the line
|
||||||
|
while( !isEndofLine( buffer[ readIdx ] ) ) {
|
||||||
|
readIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
|
||||||
|
*name = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore blanks
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in != '$' && *in != '%' ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
NameType ntype( GlobalName );
|
||||||
|
if( *in == '%' ) {
|
||||||
|
ntype = LocalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Name *currentName( ddl_nullptr );
|
||||||
|
Identifier *id( ddl_nullptr );
|
||||||
|
in = parseIdentifier( in, end, &id );
|
||||||
|
if( id ) {
|
||||||
|
currentName = new Name( ntype, id );
|
||||||
|
if( currentName ) {
|
||||||
|
*name = currentName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
|
||||||
|
*id = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore blanks
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
|
||||||
|
// staring with a number is forbidden
|
||||||
|
if( isNumeric<const char>( *in ) ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get size of id
|
||||||
|
size_t idLen( 0 );
|
||||||
|
char *start( in );
|
||||||
|
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != '(' && *in != ')' ) {
|
||||||
|
in++;
|
||||||
|
idLen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t len( idLen + 1 );
|
||||||
|
Identifier *newId = new Identifier( len, new char[ len ] );
|
||||||
|
::strncpy( newId->m_buffer, start, newId->m_len-1 );
|
||||||
|
newId->m_buffer[ newId->m_len - 1 ] = '\0';
|
||||||
|
*id = newId;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) {
|
||||||
|
type = Value::ddl_none;
|
||||||
|
len = 0;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t prim_len( 0 );
|
||||||
|
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
|
||||||
|
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
|
||||||
|
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
|
||||||
|
type = ( Value::ValueType ) i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Value::ddl_none == type ) {
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
return in;
|
||||||
|
} else {
|
||||||
|
in += prim_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok( true );
|
||||||
|
if( *in == '[' ) {
|
||||||
|
ok = false;
|
||||||
|
in++;
|
||||||
|
char *start( in );
|
||||||
|
while ( in != end ) {
|
||||||
|
in++;
|
||||||
|
if( *in == ']' ) {
|
||||||
|
len = atoi( start );
|
||||||
|
ok = true;
|
||||||
|
in++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
if( !ok ) {
|
||||||
|
type = Value::ddl_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &names ) {
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
Name *nextName( ddl_nullptr );
|
||||||
|
in = parseName( in, end, &nextName );
|
||||||
|
if( nextName ) {
|
||||||
|
names.push_back( nextName );
|
||||||
|
}
|
||||||
|
while( ',' == *in ) {
|
||||||
|
in = getNextSeparator( in, end );
|
||||||
|
if( ',' == *in ) {
|
||||||
|
in = parseName( in, end, &nextName );
|
||||||
|
if( nextName ) {
|
||||||
|
names.push_back( nextName );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) {
|
||||||
|
*boolean = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
char *start( in );
|
||||||
|
size_t len( 0 );
|
||||||
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
|
in++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
|
||||||
|
if( 0 != res ) {
|
||||||
|
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
|
||||||
|
if( 0 != res ) {
|
||||||
|
*boolean = ddl_nullptr;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
|
||||||
|
(*boolean)->setBool( false );
|
||||||
|
} else {
|
||||||
|
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
|
||||||
|
(*boolean)->setBool( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
|
||||||
|
*integer = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !isIntegerType( integerType ) ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
char *start( in );
|
||||||
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isNumeric( *start ) ) {
|
||||||
|
const int value( atoi( start ) );
|
||||||
|
*integer = ValueAllocator::allocPrimData( integerType );
|
||||||
|
switch( integerType ) {
|
||||||
|
case Value::ddl_int8:
|
||||||
|
( *integer )->setInt8( (int8) value );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int16:
|
||||||
|
( *integer )->setInt16( ( int16 ) value );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int32:
|
||||||
|
( *integer )->setInt32( ( int32 ) value );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int64:
|
||||||
|
( *integer )->setInt64( ( int64 ) value );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) {
|
||||||
|
*floating = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
char *start( in );
|
||||||
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the float value
|
||||||
|
bool ok( false );
|
||||||
|
if( isNumeric( *start ) ) {
|
||||||
|
ok = true;
|
||||||
|
} else {
|
||||||
|
if( *start == '-' ) {
|
||||||
|
if( isNumeric( *(start+1) ) ) {
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ok ) {
|
||||||
|
const float value( ( float ) atof( start ) );
|
||||||
|
*floating = ValueAllocator::allocPrimData( Value::ddl_float );
|
||||||
|
( *floating )->setFloat( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) {
|
||||||
|
*stringData = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
size_t len( 0 );
|
||||||
|
char *start( in );
|
||||||
|
if( *start == '\"' ) {
|
||||||
|
start++;
|
||||||
|
in++;
|
||||||
|
while( *in != '\"' && in != end ) {
|
||||||
|
in++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
|
||||||
|
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
|
||||||
|
( *stringData )->m_data[len] = '\0';
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) {
|
||||||
|
if( ddl_nullptr != primData ) {
|
||||||
|
( *prop ) = new Property( id );
|
||||||
|
( *prop )->m_primData = primData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
||||||
|
*data = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in != '0' ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in++;
|
||||||
|
if( *in != 'x' && *in != 'X' ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in++;
|
||||||
|
bool ok( true );
|
||||||
|
char *start( in );
|
||||||
|
int pos( 0 );
|
||||||
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
|
if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !ok ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value( 0 );
|
||||||
|
while( pos > 0 ) {
|
||||||
|
int v = hex2Decimal( *start );
|
||||||
|
pos--;
|
||||||
|
value = ( value << 4 ) | v;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
|
||||||
|
if( ddl_nullptr != *data ) {
|
||||||
|
( *data )->setUnsignedInt64( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
||||||
|
*prop = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
Identifier *id( ddl_nullptr );
|
||||||
|
in = parseIdentifier( in, end, &id );
|
||||||
|
if( ddl_nullptr != id ) {
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in == '=' ) {
|
||||||
|
in++;
|
||||||
|
in = getNextToken( in, end );
|
||||||
|
Value *primData( ddl_nullptr );
|
||||||
|
if( isInteger( in, end ) ) {
|
||||||
|
in = parseIntegerLiteral( in, end, &primData );
|
||||||
|
createPropertyWithData( id, primData, prop );
|
||||||
|
} else if( isFloat( in, end ) ) {
|
||||||
|
in = parseFloatingLiteral( in, end, &primData );
|
||||||
|
createPropertyWithData( id, primData, prop );
|
||||||
|
} else if( isStringLiteral( *in ) ) { // string data
|
||||||
|
in = parseStringLiteral( in, end, &primData );
|
||||||
|
createPropertyWithData( id, primData, prop );
|
||||||
|
} else { // reference data
|
||||||
|
std::vector<Name*> names;
|
||||||
|
in = parseReference( in, end, names );
|
||||||
|
if( !names.empty() ) {
|
||||||
|
Reference *ref = new Reference( names.size(), &names[ 0 ] );
|
||||||
|
( *prop ) = new Property( id );
|
||||||
|
( *prop )->m_ref = ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *OpenDDLParser::parseDataList( char *in, char *end, Value **data, size_t &numValues, Reference **refs, size_t &numRefs ) {
|
||||||
|
*data = ddl_nullptr;
|
||||||
|
numValues = numRefs = 0;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in == '{' ) {
|
||||||
|
in++;
|
||||||
|
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
|
||||||
|
while( '}' != *in ) {
|
||||||
|
current = ddl_nullptr;
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( isInteger( in, end ) ) {
|
||||||
|
in = parseIntegerLiteral( in, end, ¤t );
|
||||||
|
} else if( isFloat( in, end ) ) {
|
||||||
|
in = parseFloatingLiteral( in, end, ¤t );
|
||||||
|
} else if( isStringLiteral( *in ) ) {
|
||||||
|
in = parseStringLiteral( in, end, ¤t );
|
||||||
|
} else if( isHexLiteral( in, end ) ) {
|
||||||
|
in = parseHexaLiteral( in, end, ¤t );
|
||||||
|
} else { // reference data
|
||||||
|
std::vector<Name*> names;
|
||||||
|
in = parseReference( in, end, names );
|
||||||
|
if( !names.empty() ) {
|
||||||
|
Reference *ref = new Reference( names.size(), &names[ 0 ] );
|
||||||
|
*refs = ref;
|
||||||
|
numRefs = names.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ddl_nullptr != current ) {
|
||||||
|
if( ddl_nullptr == *data ) {
|
||||||
|
*data = current;
|
||||||
|
prev = current;
|
||||||
|
} else {
|
||||||
|
prev->setNext( current );
|
||||||
|
prev = current;
|
||||||
|
}
|
||||||
|
numValues++;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = getNextSeparator( in, end );
|
||||||
|
if( ',' != *in && '}' != *in && !isSpace( *in ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues ) {
|
||||||
|
DataArrayList *dataList = new DataArrayList;
|
||||||
|
dataList->m_dataList = currentValue;
|
||||||
|
dataList->m_numItems = numValues;
|
||||||
|
|
||||||
|
return dataList;
|
||||||
|
|
||||||
|
}
|
||||||
|
char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
|
||||||
|
*dataList = ddl_nullptr;
|
||||||
|
if( ddl_nullptr == in || in == end ) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
|
||||||
|
in++;
|
||||||
|
Value *currentValue( ddl_nullptr );
|
||||||
|
Reference *refs( ddl_nullptr );
|
||||||
|
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
|
||||||
|
do {
|
||||||
|
size_t numRefs( 0 ), numValues( 0 );
|
||||||
|
currentValue = ddl_nullptr;
|
||||||
|
in = parseDataList( in, end, ¤tValue, numValues, &refs, numRefs );
|
||||||
|
if( ddl_nullptr != currentValue ) {
|
||||||
|
if( ddl_nullptr == prev ) {
|
||||||
|
*dataList = createDataArrayList( currentValue, numValues );
|
||||||
|
prev = *dataList;
|
||||||
|
} else {
|
||||||
|
currentDataList = createDataArrayList( currentValue, numValues );
|
||||||
|
if( ddl_nullptr != prev ) {
|
||||||
|
prev->m_next = currentDataList;
|
||||||
|
prev = currentDataList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
|
||||||
|
in = lookForNextToken( in, end );
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *OpenDDLParser::getVersion() {
|
||||||
|
return Version;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
|
@ -0,0 +1,297 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#include <openddlparser/Value.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
Value::Value()
|
||||||
|
: m_type( ddl_none )
|
||||||
|
, m_size( 0 )
|
||||||
|
, m_data( ddl_nullptr )
|
||||||
|
, m_next( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::~Value() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setBool( bool value ) {
|
||||||
|
assert( ddl_bool == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Value::getBool() {
|
||||||
|
assert( ddl_bool == m_type );
|
||||||
|
return ( bool ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setInt8( int8 value ) {
|
||||||
|
assert( ddl_int8 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
int8 Value::getInt8() {
|
||||||
|
assert( ddl_int8 == m_type );
|
||||||
|
return ( int8 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setInt16( int16 value ) {
|
||||||
|
assert( ddl_int16 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Value::getInt16() {
|
||||||
|
assert( ddl_int16 == m_type );
|
||||||
|
return ( int16 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setInt32( int32 value ) {
|
||||||
|
assert( ddl_int32 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Value::getInt32() {
|
||||||
|
assert( ddl_int32 == m_type );
|
||||||
|
return ( int32 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setInt64( int64 value ) {
|
||||||
|
assert( ddl_int32 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 Value::getInt64() {
|
||||||
|
return ( int64 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setUnsignedInt8( uint8 value ) {
|
||||||
|
assert( ddl_unsigned_int8 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Value::getUnsignedInt8() const {
|
||||||
|
assert( ddl_unsigned_int8 == m_type );
|
||||||
|
return ( uint8 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setUnsignedInt16( uint16 value ) {
|
||||||
|
assert( ddl_unsigned_int16 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
|
||||||
|
}
|
||||||
|
uint16 Value::getUnsignedInt16() const {
|
||||||
|
assert( ddl_unsigned_int16 == m_type );
|
||||||
|
return ( uint8 ) ( *m_data );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setUnsignedInt32( uint32 value ) {
|
||||||
|
assert( ddl_unsigned_int32 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Value::getUnsignedInt32() const {
|
||||||
|
assert( ddl_unsigned_int32 == m_type );
|
||||||
|
return ( uint8 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setUnsignedInt64( uint64 value ) {
|
||||||
|
assert( ddl_unsigned_int64 == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 Value::getUnsignedInt64() const {
|
||||||
|
assert( ddl_unsigned_int64 == m_type );
|
||||||
|
return ( uint64 ) ( *m_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setFloat( float value ) {
|
||||||
|
assert( ddl_float == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
float Value::getFloat() const {
|
||||||
|
float v;
|
||||||
|
::memcpy( &v, m_data, m_size );
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setDouble( double value ) {
|
||||||
|
assert( ddl_double == m_type );
|
||||||
|
::memcpy( m_data, &value, m_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
double Value::getDouble() const {
|
||||||
|
double v;
|
||||||
|
::memcpy( &v, m_data, m_size );
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setString( const std::string &str ) {
|
||||||
|
assert( ddl_string == m_type );
|
||||||
|
::memcpy( m_data, str.c_str(), str.size() );
|
||||||
|
m_data[ str.size() ] = '\0';
|
||||||
|
}
|
||||||
|
const char *Value::getString() const {
|
||||||
|
return (const char*) m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::dump() {
|
||||||
|
switch( m_type ) {
|
||||||
|
case ddl_none:
|
||||||
|
std::cout << "None" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_bool:
|
||||||
|
std::cout << getBool() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_int8:
|
||||||
|
std::cout << getInt8() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_int16:
|
||||||
|
std::cout << getInt16() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_int32:
|
||||||
|
std::cout << getInt32() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_int64:
|
||||||
|
std::cout << getInt64() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_unsigned_int8:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_unsigned_int16:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_unsigned_int32:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_unsigned_int64:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_half:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_float:
|
||||||
|
std::cout << getFloat() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_double:
|
||||||
|
std::cout << getDouble() << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_string:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
case ddl_ref:
|
||||||
|
std::cout << "Not supported" << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Value::setNext( Value *next ) {
|
||||||
|
m_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *Value::getNext() const {
|
||||||
|
return m_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
||||||
|
if( type == Value::ddl_none || Value::ddl_types_max == type ) {
|
||||||
|
return ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *data = new Value;
|
||||||
|
data->m_type = type;
|
||||||
|
switch( type ) {
|
||||||
|
case Value::ddl_bool:
|
||||||
|
data->m_size = sizeof( bool );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int8:
|
||||||
|
data->m_size = sizeof( char );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int16:
|
||||||
|
data->m_size = sizeof( short );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int32:
|
||||||
|
data->m_size = sizeof( int );
|
||||||
|
break;
|
||||||
|
case Value::ddl_int64:
|
||||||
|
data->m_size = sizeof( long );
|
||||||
|
break;
|
||||||
|
case Value::ddl_unsigned_int8:
|
||||||
|
data->m_size = sizeof( unsigned char );
|
||||||
|
break;
|
||||||
|
case Value::ddl_unsigned_int32:
|
||||||
|
data->m_size = sizeof( unsigned int );
|
||||||
|
break;
|
||||||
|
case Value::ddl_unsigned_int64:
|
||||||
|
data->m_size = sizeof( unsigned long );
|
||||||
|
break;
|
||||||
|
case Value::ddl_half:
|
||||||
|
data->m_size = sizeof( short );
|
||||||
|
break;
|
||||||
|
case Value::ddl_float:
|
||||||
|
data->m_size = sizeof( float );
|
||||||
|
break;
|
||||||
|
case Value::ddl_double:
|
||||||
|
data->m_size = sizeof( double );
|
||||||
|
break;
|
||||||
|
case Value::ddl_string:
|
||||||
|
data->m_size = sizeof( char );
|
||||||
|
break;
|
||||||
|
case Value::ddl_ref:
|
||||||
|
data->m_size = sizeof( char );
|
||||||
|
break;
|
||||||
|
case Value::ddl_none:
|
||||||
|
case Value::ddl_types_max:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data->m_size ) {
|
||||||
|
size_t len1( len );
|
||||||
|
if( Value::ddl_string == type ) {
|
||||||
|
len1++;
|
||||||
|
}
|
||||||
|
data->m_size *= len1;
|
||||||
|
data->m_data = new unsigned char[ data->m_size ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueAllocator::releasePrimData( Value **data ) {
|
||||||
|
if( !data ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete *data;
|
||||||
|
*data = ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef OPENDDLPARSER_DDLNODE_H_INC
|
||||||
|
#define OPENDDLPARSER_DDLNODE_H_INC
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
class Value;
|
||||||
|
class OpenDDLParser;
|
||||||
|
|
||||||
|
struct Identifier;
|
||||||
|
struct Reference;
|
||||||
|
struct Property;
|
||||||
|
struct DataArrayList;
|
||||||
|
|
||||||
|
class DLL_ODDLPARSER_EXPORT DDLNode {
|
||||||
|
public:
|
||||||
|
friend class OpenDDLParser;
|
||||||
|
|
||||||
|
typedef std::vector<DDLNode*> DllNodeList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~DDLNode();
|
||||||
|
void attachParent( DDLNode *parent );
|
||||||
|
void detachParent();
|
||||||
|
DDLNode *getParent() const;
|
||||||
|
const DllNodeList &getChildNodeList() const;
|
||||||
|
void setType( const std::string &name );
|
||||||
|
const std::string &getType() const;
|
||||||
|
void setName( const std::string &name );
|
||||||
|
const std::string &getName() const;
|
||||||
|
void setProperties( Property *prop );
|
||||||
|
Property *getProperties() const;
|
||||||
|
void setValue( Value *val );
|
||||||
|
Value *getValue() const;
|
||||||
|
void setDataArrayList( DataArrayList *dtArrayList );
|
||||||
|
DataArrayList *getDataArrayList() const;
|
||||||
|
void setReferences( Reference *refs );
|
||||||
|
Reference *getReferences() const;
|
||||||
|
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
|
||||||
|
|
||||||
|
private:
|
||||||
|
DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr );
|
||||||
|
DDLNode();
|
||||||
|
DDLNode( const DDLNode & );
|
||||||
|
DDLNode &operator = ( const DDLNode & );
|
||||||
|
static void releaseNodes();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_type;
|
||||||
|
std::string m_name;
|
||||||
|
DDLNode *m_parent;
|
||||||
|
std::vector<DDLNode*> m_children;
|
||||||
|
Property *m_properties;
|
||||||
|
Value *m_value;
|
||||||
|
DataArrayList *m_dtArrayList;
|
||||||
|
Reference *m_references;
|
||||||
|
size_t m_idx;
|
||||||
|
static DllNodeList s_allocatedNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#endif // OPENDDLPARSER_DDLNODE_H_INC
|
|
@ -0,0 +1,210 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||||
|
#define OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define TAG_DLL_EXPORT __declspec(dllexport)
|
||||||
|
# define TAG_DLL_IMPORT __declspec(dllimport )
|
||||||
|
# ifdef OPENDDLPARSER_BUILD
|
||||||
|
# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT
|
||||||
|
# else
|
||||||
|
# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT
|
||||||
|
# endif // OPENDDLPARSER_BUILD
|
||||||
|
# pragma warning( disable : 4251 )
|
||||||
|
#else
|
||||||
|
# define DLL_ODDLPARSER_EXPORT
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#define BEGIN_ODDLPARSER_NS namespace ODDLParser {
|
||||||
|
#define END_ODDLPARSER_NS }
|
||||||
|
#define USE_ODDLPARSER_NS using namespace ODDLParser;
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#ifndef OPENDDL_NO_USE_CPP11
|
||||||
|
# define ddl_nullptr nullptr
|
||||||
|
#else
|
||||||
|
# define ddl_nullptr NULL
|
||||||
|
#endif // OPENDDL_NO_USE_CPP11
|
||||||
|
|
||||||
|
class DDLNode;
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
struct Name;
|
||||||
|
struct Identifier;
|
||||||
|
struct Reference;
|
||||||
|
struct Property;
|
||||||
|
struct DataArrayList;
|
||||||
|
|
||||||
|
typedef char int8;
|
||||||
|
typedef short int16;
|
||||||
|
typedef int int32;
|
||||||
|
typedef long int64;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef unsigned long uint64;
|
||||||
|
|
||||||
|
enum NameType {
|
||||||
|
GlobalName,
|
||||||
|
LocalName
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token {
|
||||||
|
public:
|
||||||
|
Token( const char *token )
|
||||||
|
: m_token( token )
|
||||||
|
, m_size( 0 ){
|
||||||
|
if( ddl_nullptr != token ) {
|
||||||
|
m_size = strlen( m_token );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Token() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t length() const {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == ( const Token &rhs ) const {
|
||||||
|
if( m_size != rhs.m_size ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int res( strncmp( m_token, rhs.m_token, m_size ) );
|
||||||
|
return ( res == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Token();
|
||||||
|
Token( const Token & );
|
||||||
|
Token &operator = ( const Token & );
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *m_token;
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
struct Name {
|
||||||
|
NameType m_type;
|
||||||
|
Identifier *m_id;
|
||||||
|
|
||||||
|
Name( NameType type, Identifier *id )
|
||||||
|
: m_type( type )
|
||||||
|
, m_id( id ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Reference {
|
||||||
|
size_t m_numRefs;
|
||||||
|
Name **m_referencedName;
|
||||||
|
|
||||||
|
Reference()
|
||||||
|
: m_numRefs( 0 )
|
||||||
|
, m_referencedName( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference( size_t numrefs, Name **names )
|
||||||
|
: m_numRefs( numrefs )
|
||||||
|
, m_referencedName( ddl_nullptr ) {
|
||||||
|
m_referencedName = new Name *[ numrefs ];
|
||||||
|
for( size_t i = 0; i < numrefs; i++ ) {
|
||||||
|
Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
|
||||||
|
m_referencedName[ i ] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Identifier {
|
||||||
|
size_t m_len;
|
||||||
|
char *m_buffer;
|
||||||
|
|
||||||
|
Identifier( size_t len, char buffer[] )
|
||||||
|
: m_len( len )
|
||||||
|
, m_buffer( buffer ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Property {
|
||||||
|
Identifier *m_id;
|
||||||
|
Value *m_primData;
|
||||||
|
Reference *m_ref;
|
||||||
|
Property *m_next;
|
||||||
|
|
||||||
|
Property( Identifier *id )
|
||||||
|
: m_id( id )
|
||||||
|
, m_primData( ddl_nullptr )
|
||||||
|
, m_ref( ddl_nullptr )
|
||||||
|
, m_next( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataArrayList {
|
||||||
|
size_t m_numItems;
|
||||||
|
Value *m_dataList;
|
||||||
|
DataArrayList *m_next;
|
||||||
|
|
||||||
|
DataArrayList()
|
||||||
|
: m_numItems( 0 )
|
||||||
|
, m_dataList( ddl_nullptr )
|
||||||
|
, m_next( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
DDLNode *m_root;
|
||||||
|
|
||||||
|
Context()
|
||||||
|
: m_root( ddl_nullptr ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BufferIt {
|
||||||
|
std::vector<char> m_buffer;
|
||||||
|
size_t m_idx;
|
||||||
|
|
||||||
|
BufferIt( const std::vector<char> &buffer )
|
||||||
|
: m_buffer( buffer )
|
||||||
|
, m_idx( 0 ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef OPENDDLPARSER_OPENDDLPARSER_H_INC
|
||||||
|
#define OPENDDLPARSER_OPENDDLPARSER_H_INC
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
#include <openddlparser/DDLNode.h>
|
||||||
|
#include <openddlparser/OpenDDLParserUtils.h>
|
||||||
|
#include <openddlparser/Value.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
class DDLNode;
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
struct Identifier;
|
||||||
|
struct Reference;
|
||||||
|
struct Property;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
T *lookForNextToken( T *in, T *end ) {
|
||||||
|
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
T *getNextToken( T *in, T *end ) {
|
||||||
|
T *tmp( in );
|
||||||
|
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
if( tmp == in ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Defines the log severity.
|
||||||
|
enum LogSeverity {
|
||||||
|
ddl_debug_msg = 0, ///< Debug message, for debugging
|
||||||
|
ddl_info_msg, ///< Info messages, normal mode
|
||||||
|
ddl_warn_msg, ///< Parser warnings
|
||||||
|
ddl_error_msg ///< Parser errors
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_ODDLPARSER_EXPORT OpenDDLParser {
|
||||||
|
public:
|
||||||
|
typedef void( *logCallback )( LogSeverity severity, const std::string &msg );
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenDDLParser();
|
||||||
|
OpenDDLParser( char *buffer, size_t len );
|
||||||
|
~OpenDDLParser();
|
||||||
|
void setLogCallback( logCallback callback );
|
||||||
|
logCallback getLogCallback() const;
|
||||||
|
void setBuffer( char *buffer, size_t len );
|
||||||
|
void setBuffer( const std::vector<char> &buffer );
|
||||||
|
const char *getBuffer() const;
|
||||||
|
size_t getBufferSize() const;
|
||||||
|
void clear();
|
||||||
|
bool parse();
|
||||||
|
char *parseNextNode( char *current, char *end );
|
||||||
|
char *parseHeader( char *in, char *end );
|
||||||
|
char *parseStructure( char *in, char *end );
|
||||||
|
char *parseStructureBody( char *in, char *end, bool &error );
|
||||||
|
void pushNode( DDLNode *node );
|
||||||
|
DDLNode *popNode();
|
||||||
|
DDLNode *top();
|
||||||
|
DDLNode *getRoot() const;
|
||||||
|
Context *getContext() const;
|
||||||
|
|
||||||
|
public: // static parser helpers
|
||||||
|
static void normalizeBuffer( std::vector<char> &buffer );
|
||||||
|
static char *parseName( char *in, char *end, Name **name );
|
||||||
|
static char *parseIdentifier( char *in, char *end, Identifier **id );
|
||||||
|
static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len );
|
||||||
|
static char *parseReference( char *in, char *end, std::vector<Name*> &names );
|
||||||
|
static char *parseBooleanLiteral( char *in, char *end, Value **boolean );
|
||||||
|
static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 );
|
||||||
|
static char *parseFloatingLiteral( char *in, char *end, Value **floating );
|
||||||
|
static char *parseStringLiteral( char *in, char *end, Value **stringData );
|
||||||
|
static char *parseHexaLiteral( char *in, char *end, Value **data );
|
||||||
|
static char *parseProperty( char *in, char *end, Property **prop );
|
||||||
|
static char *parseDataList( char *in, char *end, Value **data, size_t &numValues, Reference **refs, size_t &numRefs );
|
||||||
|
static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList );
|
||||||
|
static const char *getVersion();
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenDDLParser( const OpenDDLParser & );
|
||||||
|
OpenDDLParser &operator = ( const OpenDDLParser & );
|
||||||
|
|
||||||
|
private:
|
||||||
|
logCallback m_logCallback;
|
||||||
|
std::vector<char> m_buffer;
|
||||||
|
|
||||||
|
typedef std::vector<DDLNode*> DDLNodeStack;
|
||||||
|
DDLNodeStack m_stack;
|
||||||
|
Context *m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#endif // OPENDDLPARSER_OPENDDLPARSER_H_INC
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
||||||
|
#define OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isComment( T *in, T *end ) {
|
||||||
|
if( *in == '/' ) {
|
||||||
|
if( in + 1 != end ) {
|
||||||
|
if( *( in + 1 ) == '/' ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isUpperCase( T in ) {
|
||||||
|
return ( in >= 'A' && in <= 'Z' );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isLowerCase( T in ) {
|
||||||
|
return ( in >= 'a' && in <= 'z' );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isSpace( const T in ) {
|
||||||
|
return ( ' ' == in || '\t' == in );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isNewLine( const T in ) {
|
||||||
|
return ( '\n' == in || ( '\r' == in ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isSeparator( T in ) {
|
||||||
|
if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char chartype_table[ 256 ] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63
|
||||||
|
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127
|
||||||
|
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isNumeric( const T in ) {
|
||||||
|
return ( in >= '0' && in <= '9' );
|
||||||
|
//return ( chartype_table[in] );
|
||||||
|
/*if (in >= '0' && in <= '9' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isInteger( T *in, T *end ) {
|
||||||
|
if( in != end ) {
|
||||||
|
if( *in == '-' ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result( false );
|
||||||
|
while( '}' != *in && ',' != *in && !isSpace( *in ) && in != end ) {
|
||||||
|
result = isNumeric( *in );
|
||||||
|
if( !result ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isFloat( T *in, T *end ) {
|
||||||
|
if( in != end ) {
|
||||||
|
if( *in == '-' ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for <1>.0f
|
||||||
|
bool result( false );
|
||||||
|
while( !isSpace( *in ) && in != end ) {
|
||||||
|
if( *in == '.' ) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = isNumeric( *in );
|
||||||
|
if( !result ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for 1<.>0f
|
||||||
|
if( *in == '.' ) {
|
||||||
|
in++;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for 1.<0>f
|
||||||
|
while( !isSpace( *in ) && in != end && *in != ',' ) {
|
||||||
|
result = isNumeric( *in );
|
||||||
|
if( !result ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isCharacter( const T in ) {
|
||||||
|
return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isStringLiteral( const T in ) {
|
||||||
|
return ( in == '\"' );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isHexLiteral( T *in, T *end ) {
|
||||||
|
if( *in == '0' ) {
|
||||||
|
if( in + 1 != end ) {
|
||||||
|
if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isReference( T *in, T *end ) {
|
||||||
|
if( *in == 'r' ) {
|
||||||
|
if( *(in+1) == 'e' ) {
|
||||||
|
if( *(in+2) == 'f' ) {
|
||||||
|
if( ( in + 2 ) != end ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isEndofLine( const T in ) {
|
||||||
|
return ( '\n' == in );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
static T *getNextSeparator( T *in, T *end ) {
|
||||||
|
while( !isSeparator( *in ) || in == end ) {
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int ErrorHex2Decimal = 9999999;
|
||||||
|
|
||||||
|
inline
|
||||||
|
int hex2Decimal( char in ) {
|
||||||
|
if( isNumeric( in ) ) {
|
||||||
|
return ( in - 48 );
|
||||||
|
}
|
||||||
|
|
||||||
|
char hexCodeLower( 'a' ), hexCodeUpper( 'A' );
|
||||||
|
for( int i = 0; i<16; i++ ) {
|
||||||
|
if( in == hexCodeLower + i || in == hexCodeUpper + i ) {
|
||||||
|
return ( i+10 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorHex2Decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#endif // OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef OPENDDLPARSER_VALUE_H_INC
|
||||||
|
#define OPENDDLPARSER_VALUE_H_INC
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
///------------------------------------------------------------------------------------------------
|
||||||
|
/// @brief This class implements a value.
|
||||||
|
///
|
||||||
|
/// Values are used to store data types like boolean, integer, floats, double and many mode. To get
|
||||||
|
/// an overview please check the enum VylueType ( @see Value::ValueType ).
|
||||||
|
/// Values can be single items or lists of items. They are implemented as linked lists.
|
||||||
|
///------------------------------------------------------------------------------------------------
|
||||||
|
class DLL_ODDLPARSER_EXPORT Value {
|
||||||
|
public:
|
||||||
|
/// @brief This enum describes the data type stored in the value.
|
||||||
|
enum ValueType {
|
||||||
|
ddl_none = -1, ///< Nothing specified
|
||||||
|
ddl_bool = 0, ///< A boolean type
|
||||||
|
ddl_int8, ///< Integer type, 8 bytes
|
||||||
|
ddl_int16, ///< Integer type, 16 bytes
|
||||||
|
ddl_int32, ///< Integer type, 32 bytes
|
||||||
|
ddl_int64, ///< Integer type, 64 bytes
|
||||||
|
ddl_unsigned_int8, ///< Unsigned integer type, 8 bytes
|
||||||
|
ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes
|
||||||
|
ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes
|
||||||
|
ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes
|
||||||
|
ddl_half,
|
||||||
|
ddl_float,
|
||||||
|
ddl_double,
|
||||||
|
ddl_string,
|
||||||
|
ddl_ref,
|
||||||
|
ddl_types_max
|
||||||
|
};
|
||||||
|
|
||||||
|
Value();
|
||||||
|
~Value();
|
||||||
|
void setBool( bool value );
|
||||||
|
bool getBool();
|
||||||
|
void setInt8( int8 value );
|
||||||
|
int8 getInt8();
|
||||||
|
void setInt16( int16 value );
|
||||||
|
int16 getInt16();
|
||||||
|
void setInt32( int32 value );
|
||||||
|
int32 getInt32();
|
||||||
|
void setInt64( int64 value );
|
||||||
|
int64 getInt64();
|
||||||
|
void setUnsignedInt8( uint8 value );
|
||||||
|
uint8 getUnsignedInt8() const;
|
||||||
|
void setUnsignedInt16( uint16 value );
|
||||||
|
uint16 getUnsignedInt16() const;
|
||||||
|
void setUnsignedInt32( uint32 value );
|
||||||
|
uint32 getUnsignedInt32() const;
|
||||||
|
void setUnsignedInt64( uint64 value );
|
||||||
|
uint64 getUnsignedInt64() const;
|
||||||
|
void setFloat( float value );
|
||||||
|
float getFloat() const;
|
||||||
|
void setDouble( double value );
|
||||||
|
double getDouble() const;
|
||||||
|
void setString( const std::string &str );
|
||||||
|
const char *getString() const;
|
||||||
|
void dump();
|
||||||
|
void setNext( Value *next );
|
||||||
|
Value *getNext() const;
|
||||||
|
|
||||||
|
ValueType m_type;
|
||||||
|
size_t m_size;
|
||||||
|
unsigned char *m_data;
|
||||||
|
Value *m_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DLL_ODDLPARSER_EXPORT ValueAllocator {
|
||||||
|
static Value *allocPrimData( Value::ValueType type, size_t len = 1 );
|
||||||
|
static void releasePrimData( Value **data );
|
||||||
|
};
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
#endif // OPENDDLPARSER_VALUE_H_INC
|
|
@ -1,46 +1,46 @@
|
||||||
|
|
||||||
|
|
||||||
// ===============================================================================
|
// ===============================================================================
|
||||||
// May be included multiple times - sets structure packing to 1
|
// May be included multiple times - sets structure packing to 1
|
||||||
// for all supported compilers. #include <poppack1.h> reverts the changes.
|
// for all supported compilers. #include <poppack1.h> reverts the changes.
|
||||||
//
|
//
|
||||||
// Currently this works on the following compilers:
|
// Currently this works on the following compilers:
|
||||||
// MSVC 7,8,9
|
// MSVC 7,8,9
|
||||||
// GCC
|
// GCC
|
||||||
// BORLAND (complains about 'pack state changed but not reverted', but works)
|
// BORLAND (complains about 'pack state changed but not reverted', but works)
|
||||||
// Clang
|
// Clang
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// USAGE:
|
// USAGE:
|
||||||
//
|
//
|
||||||
// struct StructToBePacked {
|
// struct StructToBePacked {
|
||||||
// } PACK_STRUCT;
|
// } PACK_STRUCT;
|
||||||
//
|
//
|
||||||
// ===============================================================================
|
// ===============================================================================
|
||||||
|
|
||||||
#ifdef AI_PUSHPACK_IS_DEFINED
|
#ifdef AI_PUSHPACK_IS_DEFINED
|
||||||
# error poppack1.h must be included after pushpack1.h
|
# error poppack1.h must be included after pushpack1.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||||
# pragma pack(push,1)
|
# pragma pack(push,1)
|
||||||
# define PACK_STRUCT
|
# define PACK_STRUCT
|
||||||
#elif defined( __GNUC__ )
|
#elif defined( __GNUC__ )
|
||||||
# if defined(__clang__)
|
# if !defined(HOST_MINGW)
|
||||||
# define PACK_STRUCT __attribute__((__packed__))
|
# define PACK_STRUCT __attribute__((__packed__))
|
||||||
# else
|
# else
|
||||||
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# error Compiler not supported
|
# error Compiler not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
// C4103: Packing was changed after the inclusion of the header, propably missing #pragma pop
|
// C4103: Packing was changed after the inclusion of the header, propably missing #pragma pop
|
||||||
# pragma warning (disable : 4103)
|
# pragma warning (disable : 4103)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define AI_PUSHPACK_IS_DEFINED
|
#define AI_PUSHPACK_IS_DEFINED
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
#include "cexport.h"
|
#include "cexport.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
class ExporterPimpl;
|
class ExporterPimpl;
|
||||||
|
@ -72,6 +73,9 @@ namespace Assimp {
|
||||||
* #ExportToBlob is especially useful if you intend to work
|
* #ExportToBlob is especially useful if you intend to work
|
||||||
* with the data in-memory.
|
* with the data in-memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class ASSIMP_API ExportProperties;
|
||||||
|
|
||||||
class ASSIMP_API Exporter
|
class ASSIMP_API Exporter
|
||||||
// TODO: causes good ol' base class has no dll interface warning
|
// TODO: causes good ol' base class has no dll interface warning
|
||||||
//#ifdef __cplusplus
|
//#ifdef __cplusplus
|
||||||
|
@ -81,7 +85,7 @@ class ASSIMP_API Exporter
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Function pointer type of a Export worker function */
|
/** Function pointer type of a Export worker function */
|
||||||
typedef void (*fpExportFunc)(const char*,IOSystem*, const aiScene*);
|
typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
|
||||||
/** Internal description of an Assimp export format option */
|
/** Internal description of an Assimp export format option */
|
||||||
struct ExportFormatEntry
|
struct ExportFormatEntry
|
||||||
|
@ -171,8 +175,8 @@ public:
|
||||||
* Any IO handlers set via #SetIOHandler are ignored here.
|
* Any IO handlers set via #SetIOHandler are ignored here.
|
||||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
* imported scene. */
|
* imported scene. */
|
||||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
|
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||||
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
|
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -208,8 +212,8 @@ public:
|
||||||
* @return AI_SUCCESS if everything was fine.
|
* @return AI_SUCCESS if everything was fine.
|
||||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||||
* imported scene.*/
|
* imported scene.*/
|
||||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
|
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||||
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u);
|
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -309,16 +313,188 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
class ASSIMP_API ExportProperties
|
||||||
inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing )
|
|
||||||
{
|
{
|
||||||
return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing);
|
public:
|
||||||
|
// Data type to store the key hash
|
||||||
|
typedef unsigned int KeyType;
|
||||||
|
|
||||||
|
// typedefs for our four configuration maps.
|
||||||
|
// We don't need more, so there is no need for a generic solution
|
||||||
|
typedef std::map<KeyType, int> IntPropertyMap;
|
||||||
|
typedef std::map<KeyType, float> FloatPropertyMap;
|
||||||
|
typedef std::map<KeyType, std::string> StringPropertyMap;
|
||||||
|
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Standard constructor
|
||||||
|
* @see ExportProperties()
|
||||||
|
*/
|
||||||
|
|
||||||
|
ExportProperties();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Copy constructor.
|
||||||
|
*
|
||||||
|
* This copies the configuration properties of another ExportProperties.
|
||||||
|
* @see ExportProperties(const ExportProperties& other)
|
||||||
|
*/
|
||||||
|
ExportProperties(const ExportProperties& other);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Set an integer configuration property.
|
||||||
|
* @param szName Name of the property. All supported properties
|
||||||
|
* are defined in the aiConfig.g header (all constants share the
|
||||||
|
* prefix AI_CONFIG_XXX and are simple strings).
|
||||||
|
* @param iValue New value of the property
|
||||||
|
* @param bWasExisting Optional pointer to receive true if the
|
||||||
|
* property was set before. The new value replaces the previous value
|
||||||
|
* in this case.
|
||||||
|
* @note Property of different types (float, int, string ..) are kept
|
||||||
|
* on different stacks, so calling SetPropertyInteger() for a
|
||||||
|
* floating-point property has no effect - the loader will call
|
||||||
|
* GetPropertyFloat() to read the property, but it won't be there.
|
||||||
|
*/
|
||||||
|
void SetPropertyInteger(const char* szName, int iValue,
|
||||||
|
bool* bWasExisting = NULL);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Set a boolean configuration property. Boolean properties
|
||||||
|
* are stored on the integer stack internally so it's possible
|
||||||
|
* to set them via #SetPropertyBool and query them with
|
||||||
|
* #GetPropertyBool and vice versa.
|
||||||
|
* @see SetPropertyInteger()
|
||||||
|
*/
|
||||||
|
void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {
|
||||||
|
SetPropertyInteger(szName,value,bWasExisting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Set a floating-point configuration property.
|
||||||
|
* @see SetPropertyInteger()
|
||||||
|
*/
|
||||||
|
void SetPropertyFloat(const char* szName, float fValue,
|
||||||
|
bool* bWasExisting = NULL);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Set a string configuration property.
|
||||||
|
* @see SetPropertyInteger()
|
||||||
|
*/
|
||||||
|
void SetPropertyString(const char* szName, const std::string& sValue,
|
||||||
|
bool* bWasExisting = NULL);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Set a matrix configuration property.
|
||||||
|
* @see SetPropertyInteger()
|
||||||
|
*/
|
||||||
|
void SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue,
|
||||||
|
bool* bWasExisting = NULL);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get a configuration property.
|
||||||
|
* @param szName Name of the property. All supported properties
|
||||||
|
* are defined in the aiConfig.g header (all constants share the
|
||||||
|
* prefix AI_CONFIG_XXX).
|
||||||
|
* @param iErrorReturn Value that is returned if the property
|
||||||
|
* is not found.
|
||||||
|
* @return Current value of the property
|
||||||
|
* @note Property of different types (float, int, string ..) are kept
|
||||||
|
* on different lists, so calling SetPropertyInteger() for a
|
||||||
|
* floating-point property has no effect - the loader will call
|
||||||
|
* GetPropertyFloat() to read the property, but it won't be there.
|
||||||
|
*/
|
||||||
|
int GetPropertyInteger(const char* szName,
|
||||||
|
int iErrorReturn = 0xffffffff) const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get a boolean configuration property. Boolean properties
|
||||||
|
* are stored on the integer stack internally so it's possible
|
||||||
|
* to set them via #SetPropertyBool and query them with
|
||||||
|
* #GetPropertyBool and vice versa.
|
||||||
|
* @see GetPropertyInteger()
|
||||||
|
*/
|
||||||
|
bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
|
||||||
|
return GetPropertyInteger(szName,bErrorReturn)!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get a floating-point configuration property
|
||||||
|
* @see GetPropertyInteger()
|
||||||
|
*/
|
||||||
|
float GetPropertyFloat(const char* szName,
|
||||||
|
float fErrorReturn = 10e10f) const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get a string configuration property
|
||||||
|
*
|
||||||
|
* The return value remains valid until the property is modified.
|
||||||
|
* @see GetPropertyInteger()
|
||||||
|
*/
|
||||||
|
const std::string GetPropertyString(const char* szName,
|
||||||
|
const std::string& sErrorReturn = "") const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get a matrix configuration property
|
||||||
|
*
|
||||||
|
* The return value remains valid until the property is modified.
|
||||||
|
* @see GetPropertyInteger()
|
||||||
|
*/
|
||||||
|
const aiMatrix4x4 GetPropertyMatrix(const char* szName,
|
||||||
|
const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Determine a integer configuration property has been set.
|
||||||
|
* @see HasPropertyInteger()
|
||||||
|
*/
|
||||||
|
bool HasPropertyInteger(const char* szName) const;
|
||||||
|
|
||||||
|
/** Determine a boolean configuration property has been set.
|
||||||
|
* @see HasPropertyBool()
|
||||||
|
*/
|
||||||
|
bool HasPropertyBool(const char* szName) const;
|
||||||
|
|
||||||
|
/** Determine a boolean configuration property has been set.
|
||||||
|
* @see HasPropertyFloat()
|
||||||
|
*/
|
||||||
|
bool HasPropertyFloat(const char* szName) const;
|
||||||
|
|
||||||
|
/** Determine a String configuration property has been set.
|
||||||
|
* @see HasPropertyString()
|
||||||
|
*/
|
||||||
|
bool HasPropertyString(const char* szName) const;
|
||||||
|
|
||||||
|
/** Determine a Matrix configuration property has been set.
|
||||||
|
* @see HasPropertyMatrix()
|
||||||
|
*/
|
||||||
|
bool HasPropertyMatrix(const char* szName) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** List of integer properties */
|
||||||
|
IntPropertyMap mIntProperties;
|
||||||
|
|
||||||
|
/** List of floating-point properties */
|
||||||
|
FloatPropertyMap mFloatProperties;
|
||||||
|
|
||||||
|
/** List of string properties */
|
||||||
|
StringPropertyMap mStringProperties;
|
||||||
|
|
||||||
|
/** List of Matrix properties */
|
||||||
|
MatrixPropertyMap mMatrixProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing, const ExportProperties* pProperties)
|
||||||
|
{
|
||||||
|
return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing )
|
inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing);
|
return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
|
@ -879,4 +879,15 @@ enum aiComponent
|
||||||
|
|
||||||
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
|
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------- All the Export defines ------------
|
||||||
|
|
||||||
|
/** @brief Specifies the xfile use double for real values of float
|
||||||
|
*
|
||||||
|
* Property type: Bool. Default value: false.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
|
||||||
|
|
||||||
|
|
||||||
#endif // !! AI_CONFIG_H_INC
|
#endif // !! AI_CONFIG_H_INC
|
||||||
|
|
|
@ -1,45 +1,54 @@
|
||||||
<project name="jassimp" basedir="." default="all">
|
<project name="jassimp" basedir="." default="all">
|
||||||
<property name="native-src.dir" value="jassimp-native/src" />
|
<property name="native-src.dir" value="jassimp-native/src" />
|
||||||
<property name="src.dir" value="jassimp/src" />
|
<property name="src.dir" value="jassimp/src" />
|
||||||
<property name="jassimp.lwjgl-src.dir" value="jassimp.lwjgl/src" />
|
<property name="jassimp.lwjgl-src.dir" value="jassimp.lwjgl/src" />
|
||||||
<property name="build.dir" value="jassimp/bin" />
|
<property name="build.dir" value="jassimp/bin" />
|
||||||
<property name="dist.dir" value="dist" />
|
<property name="dist.dir" value="dist" />
|
||||||
<property name="doc.dir" value="doc" />
|
<property name="doc.dir" value="doc" />
|
||||||
|
<property environment="env"/>
|
||||||
<path id="classpath">
|
<property name="ndk.dir" value="${env.NDK_HOME}" />
|
||||||
</path>
|
<property name="my.dir" value="${env.PWD}" />
|
||||||
|
|
||||||
<target name="compile">
|
<path id="classpath">
|
||||||
<delete dir="${build.dir}" />
|
</path>
|
||||||
<mkdir dir="${build.dir}" />
|
|
||||||
<javac classpathref="classpath" destdir="${build.dir}" srcdir="${src.dir}"
|
|
||||||
source="1.6" target="1.6" includeantruntime="false">
|
|
||||||
</javac>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="jni_header">
|
<target name="compile">
|
||||||
<mkdir dir="${native-src.dir}" />
|
<delete dir="${build.dir}" />
|
||||||
<javah outputfile="${native-src.dir}/jassimp.h" force="yes">
|
<mkdir dir="${build.dir}" />
|
||||||
<classpath>
|
<javac classpathref="classpath" destdir="${build.dir}" srcdir="${src.dir}"
|
||||||
<pathelement path="${build.dir}" />
|
source="1.6" target="1.6" includeantruntime="false">
|
||||||
</classpath>
|
</javac>
|
||||||
<class name="jassimp.Jassimp" />
|
</target>
|
||||||
</javah>
|
|
||||||
</target>
|
<target name="jni_header">
|
||||||
|
<mkdir dir="${native-src.dir}" />
|
||||||
<target name="package" depends="compile">
|
<javah outputfile="${native-src.dir}/jassimp.h" force="yes">
|
||||||
<jar destfile="${dist.dir}/jassimp.jar" basedir="${build.dir}">
|
<classpath>
|
||||||
</jar>
|
<pathelement path="${build.dir}" />
|
||||||
</target>
|
</classpath>
|
||||||
|
<class name="jassimp.Jassimp" />
|
||||||
|
</javah>
|
||||||
<target name="doc">
|
</target>
|
||||||
<delete dir="${doc.dir}" />
|
|
||||||
<javadoc access="public" author="false" destdir="${doc.dir}"
|
<target name="ndk-jni" depends="package">
|
||||||
sourcepath="${src.dir}">
|
<exec executable="${ndk.dir}/ndk-build">
|
||||||
</javadoc>
|
<arg line="all NDK_PROJECT_PATH=${my.dir}/workspaces/Android-NDK"/>
|
||||||
</target>
|
</exec>
|
||||||
|
</target>
|
||||||
<target name="all" depends="package, doc">
|
|
||||||
</target>
|
<target name="package" depends="compile">
|
||||||
</project>
|
<jar destfile="${dist.dir}/jassimp.jar" basedir="${build.dir}">
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
|
||||||
|
<target name="doc">
|
||||||
|
<delete dir="${doc.dir}" />
|
||||||
|
<javadoc access="public" author="false" destdir="${doc.dir}"
|
||||||
|
sourcepath="${src.dir}">
|
||||||
|
</javadoc>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all" depends="package, doc">
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := jassimp
|
||||||
|
LOCAL_SRC_FILES := src/jassimp.cpp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += -DJNI_LOG
|
||||||
|
|
||||||
|
#LOCAL_STATIC_LIBRARIES := assimp_static
|
||||||
|
LOCAL_SHARED_LIBRARIES := assimp
|
||||||
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
|
@ -5,12 +5,16 @@
|
||||||
|
|
||||||
|
|
||||||
#ifdef JNI_LOG
|
#ifdef JNI_LOG
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include <android/log.h>
|
||||||
|
#define lprintf(...) __android_log_print(ANDROID_LOG_VERBOSE, __func__, __VA_ARGS__)
|
||||||
|
#else
|
||||||
#define lprintf(...) printf (__VA_ARGS__)
|
#define lprintf(...) printf (__VA_ARGS__)
|
||||||
|
#endif /* ANDROID */
|
||||||
#else
|
#else
|
||||||
#define lprintf
|
#define lprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static bool createInstance(JNIEnv *env, const char* className, jobject& newInstance)
|
static bool createInstance(JNIEnv *env, const char* className, jobject& newInstance)
|
||||||
{
|
{
|
||||||
jclass clazz = env->FindClass(className);
|
jclass clazz = env->FindClass(className);
|
||||||
|
@ -30,6 +34,7 @@ static bool createInstance(JNIEnv *env, const char* className, jobject& newInsta
|
||||||
}
|
}
|
||||||
|
|
||||||
newInstance = env->NewObject(clazz, ctr_id);
|
newInstance = env->NewObject(clazz, ctr_id);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == newInstance)
|
if (NULL == newInstance)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +46,7 @@ static bool createInstance(JNIEnv *env, const char* className, jobject& newInsta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool createInstance(JNIEnv *env, const char* className, const char* signature, const jvalue* params, jobject& newInstance)
|
static bool createInstance(JNIEnv *env, const char* className, const char* signature,/* const*/ jvalue* params, jobject& newInstance)
|
||||||
{
|
{
|
||||||
jclass clazz = env->FindClass(className);
|
jclass clazz = env->FindClass(className);
|
||||||
|
|
||||||
|
@ -60,6 +65,7 @@ static bool createInstance(JNIEnv *env, const char* className, const char* signa
|
||||||
}
|
}
|
||||||
|
|
||||||
newInstance = env->NewObjectA(clazz, ctr_id, params);
|
newInstance = env->NewObjectA(clazz, ctr_id, params);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == newInstance)
|
if (NULL == newInstance)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +88,7 @@ static bool getField(JNIEnv *env, jobject object, const char* fieldName, const c
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
|
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == fieldId)
|
if (NULL == fieldId)
|
||||||
{
|
{
|
||||||
|
@ -106,6 +113,7 @@ static bool setIntField(JNIEnv *env, jobject object, const char* fieldName, jint
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "I");
|
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "I");
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == fieldId)
|
if (NULL == fieldId)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +138,7 @@ static bool setFloatField(JNIEnv *env, jobject object, const char* fieldName, jf
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "F");
|
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "F");
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == fieldId)
|
if (NULL == fieldId)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +163,7 @@ static bool setObjectField(JNIEnv *env, jobject object, const char* fieldName, c
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
|
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == fieldId)
|
if (NULL == fieldId)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +202,7 @@ static bool getStaticField(JNIEnv *env, const char* className, const char* field
|
||||||
|
|
||||||
|
|
||||||
static bool call(JNIEnv *env, jobject object, const char* typeName, const char* methodName,
|
static bool call(JNIEnv *env, jobject object, const char* typeName, const char* methodName,
|
||||||
const char* signature, const jvalue* params)
|
const char* signature,/* const*/ jvalue* params)
|
||||||
{
|
{
|
||||||
jclass clazz = env->FindClass(typeName);
|
jclass clazz = env->FindClass(typeName);
|
||||||
|
|
||||||
|
@ -203,6 +213,7 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID mid = env->GetMethodID(clazz, methodName, signature);
|
jmethodID mid = env->GetMethodID(clazz, methodName, signature);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
if (NULL == mid)
|
if (NULL == mid)
|
||||||
{
|
{
|
||||||
|
@ -210,6 +221,27 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jboolean jReturnValue = env->CallBooleanMethod(object, mid, params[0].l);
|
||||||
|
|
||||||
|
return (bool)jReturnValue;
|
||||||
|
}
|
||||||
|
static bool callv(JNIEnv *env, jobject object, const char* typeName,
|
||||||
|
const char* methodName, const char* signature,/* const*/ jvalue* params) {
|
||||||
|
jclass clazz = env->FindClass(typeName);
|
||||||
|
|
||||||
|
if (NULL == clazz) {
|
||||||
|
lprintf("could not find class %s\n", typeName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID mid = env->GetMethodID(clazz, methodName, signature);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
|
if (NULL == mid) {
|
||||||
|
lprintf("could not find method %s with signature %s in type %s\n", methodName, signature, typeName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
env->CallVoidMethodA(object, mid, params);
|
env->CallVoidMethodA(object, mid, params);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -217,7 +249,7 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
|
||||||
|
|
||||||
|
|
||||||
static bool callStaticObject(JNIEnv *env, const char* typeName, const char* methodName,
|
static bool callStaticObject(JNIEnv *env, const char* typeName, const char* methodName,
|
||||||
const char* signature, const jvalue* params, jobject& returnValue)
|
const char* signature,/* const*/ jvalue* params, jobject& returnValue)
|
||||||
{
|
{
|
||||||
jclass clazz = env->FindClass(typeName);
|
jclass clazz = env->FindClass(typeName);
|
||||||
|
|
||||||
|
@ -252,7 +284,7 @@ static bool copyBuffer(JNIEnv *env, jobject jMesh, const char* jBufferName, void
|
||||||
|
|
||||||
if (env->GetDirectBufferCapacity(jBuffer) != size)
|
if (env->GetDirectBufferCapacity(jBuffer) != size)
|
||||||
{
|
{
|
||||||
lprintf("invalid direct buffer, expected %u, got %u\n", size, env->GetDirectBufferCapacity(jBuffer));
|
lprintf("invalid direct buffer, expected %u, got %llu\n", size, env->GetDirectBufferCapacity(jBuffer));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +315,7 @@ static bool copyBufferArray(JNIEnv *env, jobject jMesh, const char* jBufferName,
|
||||||
|
|
||||||
if (env->GetDirectBufferCapacity(jBuffer) != size)
|
if (env->GetDirectBufferCapacity(jBuffer) != size)
|
||||||
{
|
{
|
||||||
lprintf("invalid direct buffer, expected %u, got %u\n", size, env->GetDirectBufferCapacity(jBuffer));
|
lprintf("invalid direct buffer, expected %u, got %llu\n", size, env->GetDirectBufferCapacity(jBuffer));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +370,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
/* set general mesh data in java */
|
/* set general mesh data in java */
|
||||||
jvalue setTypesParams[1];
|
jvalue setTypesParams[1];
|
||||||
setTypesParams[0].i = cMesh->mPrimitiveTypes;
|
setTypesParams[0].i = cMesh->mPrimitiveTypes;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "setPrimitiveTypes", "(I)V", setTypesParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "setPrimitiveTypes", "(I)V", setTypesParams))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -380,7 +412,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
allocateBuffersParams[1].i = cMesh->mNumFaces;
|
allocateBuffersParams[1].i = cMesh->mNumFaces;
|
||||||
allocateBuffersParams[2].z = isPureTriangle;
|
allocateBuffersParams[2].z = isPureTriangle;
|
||||||
allocateBuffersParams[3].i = (jint) faceBufferSize;
|
allocateBuffersParams[3].i = (jint) faceBufferSize;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateBuffers", "(IIZI)V", allocateBuffersParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateBuffers", "(IIZI)V", allocateBuffersParams))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -470,7 +502,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
jvalue allocateDataChannelParams[2];
|
jvalue allocateDataChannelParams[2];
|
||||||
allocateDataChannelParams[0].i = 0;
|
allocateDataChannelParams[0].i = 0;
|
||||||
allocateDataChannelParams[1].i = 0;
|
allocateDataChannelParams[1].i = 0;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
||||||
{
|
{
|
||||||
lprintf("could not allocate normal data channel\n");
|
lprintf("could not allocate normal data channel\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -491,7 +523,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
jvalue allocateDataChannelParams[2];
|
jvalue allocateDataChannelParams[2];
|
||||||
allocateDataChannelParams[0].i = 1;
|
allocateDataChannelParams[0].i = 1;
|
||||||
allocateDataChannelParams[1].i = 0;
|
allocateDataChannelParams[1].i = 0;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
||||||
{
|
{
|
||||||
lprintf("could not allocate tangents data channel\n");
|
lprintf("could not allocate tangents data channel\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -512,7 +544,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
jvalue allocateDataChannelParams[2];
|
jvalue allocateDataChannelParams[2];
|
||||||
allocateDataChannelParams[0].i = 2;
|
allocateDataChannelParams[0].i = 2;
|
||||||
allocateDataChannelParams[1].i = 0;
|
allocateDataChannelParams[1].i = 0;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
||||||
{
|
{
|
||||||
lprintf("could not allocate bitangents data channel\n");
|
lprintf("could not allocate bitangents data channel\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -535,7 +567,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
jvalue allocateDataChannelParams[2];
|
jvalue allocateDataChannelParams[2];
|
||||||
allocateDataChannelParams[0].i = 3;
|
allocateDataChannelParams[0].i = 3;
|
||||||
allocateDataChannelParams[1].i = c;
|
allocateDataChannelParams[1].i = c;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
||||||
{
|
{
|
||||||
lprintf("could not allocate colorset data channel\n");
|
lprintf("could not allocate colorset data channel\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -574,7 +606,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
}
|
}
|
||||||
|
|
||||||
allocateDataChannelParams[1].i = c;
|
allocateDataChannelParams[1].i = c;
|
||||||
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
|
||||||
{
|
{
|
||||||
lprintf("could not allocate texture coordinates data channel\n");
|
lprintf("could not allocate texture coordinates data channel\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -671,7 +703,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapParams[0].l = jMatrixArr;
|
wrapParams[0].l = jMatrixArr;
|
||||||
jobject jMatrix;
|
jobject jMatrix;
|
||||||
|
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapParams, jMatrix))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapMatrix", "([F)Ljava/lang/Object;", wrapParams, jMatrix))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -701,6 +733,8 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
env->DeleteLocalRef(jMeshes);
|
||||||
|
env->DeleteLocalRef(jMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -719,7 +753,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
|
||||||
wrapMatParams[0].l = jMatrixArr;
|
wrapMatParams[0].l = jMatrixArr;
|
||||||
jobject jMatrix;
|
jobject jMatrix;
|
||||||
|
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapMatParams, jMatrix))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapMatrix", "([F)Ljava/lang/Object;", wrapMatParams, jMatrix))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -749,7 +783,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
|
||||||
wrapNodeParams[2].l = jMeshrefArr;
|
wrapNodeParams[2].l = jMeshrefArr;
|
||||||
wrapNodeParams[3].l = jNodeName;
|
wrapNodeParams[3].l = jNodeName;
|
||||||
jobject jNode;
|
jobject jNode;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapSceneNode",
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapSceneNode",
|
||||||
"(Ljava/lang/Object;Ljava/lang/Object;[ILjava/lang/String;)Ljava/lang/Object;", wrapNodeParams, jNode))
|
"(Ljava/lang/Object;Ljava/lang/Object;[ILjava/lang/String;)Ljava/lang/Object;", wrapNodeParams, jNode))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -805,7 +839,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
{
|
{
|
||||||
const aiMaterial* cMaterial = cScene->mMaterials[m];
|
const aiMaterial* cMaterial = cScene->mMaterials[m];
|
||||||
|
|
||||||
lprintf("converting material ...\n", m);
|
lprintf("converting material %d ...\n", m);
|
||||||
|
|
||||||
jobject jMaterial = NULL;
|
jobject jMaterial = NULL;
|
||||||
|
|
||||||
|
@ -842,7 +876,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
setNumberParams[0].i = ttInd;
|
setNumberParams[0].i = ttInd;
|
||||||
setNumberParams[1].i = num;
|
setNumberParams[1].i = num;
|
||||||
|
|
||||||
if (!call(env, jMaterial, "jassimp/AiMaterial", "setTextureNumber", "(II)V", setNumberParams))
|
if (!callv(env, jMaterial, "jassimp/AiMaterial", "setTextureNumber", "(II)V", setNumberParams))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -880,7 +914,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapColorParams[0].f = ((float*) cProperty->mData)[0];
|
wrapColorParams[0].f = ((float*) cProperty->mData)[0];
|
||||||
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
||||||
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
|
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jData))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jData))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -905,7 +939,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
||||||
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
|
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
|
||||||
wrapColorParams[3].f = ((float*) cProperty->mData)[3];
|
wrapColorParams[3].f = ((float*) cProperty->mData)[3];
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor4", "(FFFF)Ljava/lang/Object;", wrapColorParams, jData))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor4", "(FFFF)Ljava/lang/Object;", wrapColorParams, jData))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1171,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapColorParams[1].f = cLight->mColorDiffuse.g;
|
wrapColorParams[1].f = cLight->mColorDiffuse.g;
|
||||||
wrapColorParams[2].f = cLight->mColorDiffuse.b;
|
wrapColorParams[2].f = cLight->mColorDiffuse.b;
|
||||||
jobject jDiffuse;
|
jobject jDiffuse;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jDiffuse))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jDiffuse))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1146,7 +1180,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapColorParams[1].f = cLight->mColorSpecular.g;
|
wrapColorParams[1].f = cLight->mColorSpecular.g;
|
||||||
wrapColorParams[2].f = cLight->mColorSpecular.b;
|
wrapColorParams[2].f = cLight->mColorSpecular.b;
|
||||||
jobject jSpecular;
|
jobject jSpecular;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jSpecular))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jSpecular))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1189,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapColorParams[1].f = cLight->mColorAmbient.g;
|
wrapColorParams[1].f = cLight->mColorAmbient.g;
|
||||||
wrapColorParams[2].f = cLight->mColorAmbient.b;
|
wrapColorParams[2].f = cLight->mColorAmbient.b;
|
||||||
jobject jAmbient;
|
jobject jAmbient;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jAmbient))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jAmbient))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1167,7 +1201,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapVec3Params[1].f = cLight->mPosition.y;
|
wrapVec3Params[1].f = cLight->mPosition.y;
|
||||||
wrapVec3Params[2].f = cLight->mPosition.z;
|
wrapVec3Params[2].f = cLight->mPosition.z;
|
||||||
jobject jPosition;
|
jobject jPosition;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jPosition))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jPosition))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1210,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapVec3Params[1].f = cLight->mPosition.y;
|
wrapVec3Params[1].f = cLight->mPosition.y;
|
||||||
wrapVec3Params[2].f = cLight->mPosition.z;
|
wrapVec3Params[2].f = cLight->mPosition.z;
|
||||||
jobject jDirection;
|
jobject jDirection;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jDirection))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jDirection))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1242,7 +1276,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapPositionParams[1].f = cCamera->mPosition.y;
|
wrapPositionParams[1].f = cCamera->mPosition.y;
|
||||||
wrapPositionParams[2].f = cCamera->mPosition.z;
|
wrapPositionParams[2].f = cCamera->mPosition.z;
|
||||||
jobject jPosition;
|
jobject jPosition;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jPosition))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jPosition))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1251,7 +1285,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapPositionParams[1].f = cCamera->mUp.y;
|
wrapPositionParams[1].f = cCamera->mUp.y;
|
||||||
wrapPositionParams[2].f = cCamera->mUp.z;
|
wrapPositionParams[2].f = cCamera->mUp.z;
|
||||||
jobject jUp;
|
jobject jUp;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jUp))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jUp))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1260,7 +1294,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
wrapPositionParams[1].f = cCamera->mLookAt.y;
|
wrapPositionParams[1].f = cCamera->mLookAt.y;
|
||||||
wrapPositionParams[2].f = cCamera->mLookAt.z;
|
wrapPositionParams[2].f = cCamera->mLookAt.z;
|
||||||
jobject jLookAt;
|
jobject jLookAt;
|
||||||
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jLookAt))
|
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jLookAt))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1306,6 +1340,62 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getVKeysize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(aiVectorKey);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getQKeysize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(aiQuatKey);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getV3Dsize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(aiVector3D);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getfloatsize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(float);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getintsize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(int);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getuintsize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(unsigned int);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getdoublesize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(double);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getlongsize
|
||||||
|
(JNIEnv *env, jclass jClazz)
|
||||||
|
{
|
||||||
|
const int res = sizeof(long);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString
|
JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString
|
||||||
(JNIEnv *env, jclass jClazz)
|
(JNIEnv *env, jclass jClazz)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,23 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getVKeysize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getQKeysize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getV3Dsize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getfloatsize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getintsize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getuintsize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getdoublesize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
JNIEXPORT jint JNICALL Java_jassimp_Jassimp_getlongsize
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: jassimp_Jassimp
|
* Class: jassimp_Jassimp
|
||||||
* Method: getErrorString
|
* Method: getErrorString
|
||||||
|
|
|
@ -140,13 +140,17 @@ public final class AiMesh {
|
||||||
/**
|
/**
|
||||||
* Number of bytes per float value.
|
* Number of bytes per float value.
|
||||||
*/
|
*/
|
||||||
private static final int SIZEOF_FLOAT = 4;
|
private static final int SIZEOF_FLOAT = Jassimp.NATIVE_FLOAT_SIZE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of bytes per int value.
|
* Number of bytes per int value.
|
||||||
*/
|
*/
|
||||||
private static final int SIZEOF_INT = 4;
|
private static final int SIZEOF_INT = Jassimp.NATIVE_INT_SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of an AiVector3D in the native world.
|
||||||
|
*/
|
||||||
|
private static final int SIZEOF_V3D = Jassimp.NATIVE_AIVEKTOR3D_SIZE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library - Java Binding (jassimp)
|
Open Asset Import Library - Java Binding (jassimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -68,19 +68,19 @@ import java.nio.ByteOrder;
|
||||||
*/
|
*/
|
||||||
public final class AiNodeAnim {
|
public final class AiNodeAnim {
|
||||||
/**
|
/**
|
||||||
* Size of one position key entry (includes padding).
|
* Size of one position key entry.
|
||||||
*/
|
*/
|
||||||
private static final int POS_KEY_SIZE = 24;
|
private static final int POS_KEY_SIZE = Jassimp.NATIVE_AIVEKTORKEY_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of one rotation key entry.
|
* Size of one rotation key entry.
|
||||||
*/
|
*/
|
||||||
private static final int ROT_KEY_SIZE = 24;
|
private static final int ROT_KEY_SIZE = Jassimp.NATIVE_AIQUATKEY_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of one scaling key entry (includes padding).
|
* Size of one scaling key entry.
|
||||||
*/
|
*/
|
||||||
private static final int SCALE_KEY_SIZE = 24;
|
private static final int SCALE_KEY_SIZE = Jassimp.NATIVE_AIVEKTORKEY_SIZE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,14 +103,13 @@ public final class AiNodeAnim {
|
||||||
m_preState = AiAnimBehavior.fromRawValue(preBehavior);
|
m_preState = AiAnimBehavior.fromRawValue(preBehavior);
|
||||||
m_postState = AiAnimBehavior.fromRawValue(postBehavior);
|
m_postState = AiAnimBehavior.fromRawValue(postBehavior);
|
||||||
|
|
||||||
/* c data is padded -> 24 bytes with 20 bytes data */
|
|
||||||
m_posKeys = ByteBuffer.allocateDirect(numPosKeys * POS_KEY_SIZE);
|
m_posKeys = ByteBuffer.allocateDirect(numPosKeys * POS_KEY_SIZE);
|
||||||
m_posKeys.order(ByteOrder.nativeOrder());
|
m_posKeys.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
m_rotKeys = ByteBuffer.allocateDirect(numRotKeys * 24);
|
m_rotKeys = ByteBuffer.allocateDirect(numRotKeys * ROT_KEY_SIZE);
|
||||||
m_rotKeys.order(ByteOrder.nativeOrder());
|
m_rotKeys.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
m_scaleKeys = ByteBuffer.allocateDirect(numScaleKeys * 24);
|
m_scaleKeys = ByteBuffer.allocateDirect(numScaleKeys * SCALE_KEY_SIZE);
|
||||||
m_scaleKeys.order(ByteOrder.nativeOrder());
|
m_scaleKeys.order(ByteOrder.nativeOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ public final class AiNodeAnim {
|
||||||
* Returns the buffer with position keys of this animation channel.<p>
|
* Returns the buffer with position keys of this animation channel.<p>
|
||||||
*
|
*
|
||||||
* Position keys consist of a time value (double) and a position (3D vector
|
* Position keys consist of a time value (double) and a position (3D vector
|
||||||
* of floats), resulting in a total of 24 bytes per entry with padding.
|
* of floats), resulting in a total of 20 bytes per entry.
|
||||||
* The buffer contains {@link #getNumPosKeys()} of these entries.<p>
|
* The buffer contains {@link #getNumPosKeys()} of these entries.<p>
|
||||||
*
|
*
|
||||||
* If there are position keys, there will also be at least one
|
* If there are position keys, there will also be at least one
|
||||||
|
@ -340,7 +339,7 @@ public final class AiNodeAnim {
|
||||||
* Returns the buffer with scaling keys of this animation channel.<p>
|
* Returns the buffer with scaling keys of this animation channel.<p>
|
||||||
*
|
*
|
||||||
* Scaling keys consist of a time value (double) and a 3D vector of floats,
|
* Scaling keys consist of a time value (double) and a 3D vector of floats,
|
||||||
* resulting in a total of 24 bytes per entry with padding. The buffer
|
* resulting in a total of 20 bytes per entry. The buffer
|
||||||
* contains {@link #getNumScaleKeys()} of these entries.<p>
|
* contains {@link #getNumScaleKeys()} of these entries.<p>
|
||||||
*
|
*
|
||||||
* If there are scaling keys, there will also be at least one
|
* If there are scaling keys, there will also be at least one
|
||||||
|
|
|
@ -96,6 +96,48 @@ public final class Jassimp {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of a struct or ptimitive.<p>
|
||||||
|
*
|
||||||
|
* @return the result of sizeof call
|
||||||
|
*/
|
||||||
|
public static native int getVKeysize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getQKeysize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getV3Dsize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getfloatsize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getintsize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getuintsize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getdoublesize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getVKeysize
|
||||||
|
*/
|
||||||
|
public static native int getlongsize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable error description.<p>
|
* Returns a human readable error description.<p>
|
||||||
*
|
*
|
||||||
|
@ -249,8 +291,24 @@ public final class Jassimp {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final int NATIVE_AIVEKTORKEY_SIZE;
|
||||||
|
public static final int NATIVE_AIQUATKEY_SIZE;
|
||||||
|
public static final int NATIVE_AIVEKTOR3D_SIZE;
|
||||||
|
public static final int NATIVE_FLOAT_SIZE;
|
||||||
|
public static final int NATIVE_INT_SIZE;
|
||||||
|
public static final int NATIVE_UINT_SIZE;
|
||||||
|
public static final int NATIVE_DOUBLE_SIZE;
|
||||||
|
public static final int NATIVE_LONG_SIZE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("jassimp");
|
System.loadLibrary("jassimp");
|
||||||
|
NATIVE_AIVEKTORKEY_SIZE = getVKeysize();
|
||||||
|
NATIVE_AIQUATKEY_SIZE = getQKeysize();
|
||||||
|
NATIVE_AIVEKTOR3D_SIZE = getV3Dsize();
|
||||||
|
NATIVE_FLOAT_SIZE = getfloatsize();
|
||||||
|
NATIVE_INT_SIZE = getintsize();
|
||||||
|
NATIVE_UINT_SIZE = getuintsize();
|
||||||
|
NATIVE_DOUBLE_SIZE = getdoublesize();
|
||||||
|
NATIVE_LONG_SIZE = getlongsize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
entities and data types contained"""
|
entities and data types contained"""
|
||||||
|
|
||||||
import sys, os, re
|
import sys, os, re
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
re_match_entity = re.compile(r"""
|
re_match_entity = re.compile(r"""
|
||||||
ENTITY\s+(\w+)\s* # 'ENTITY foo'
|
ENTITY\s+(\w+)\s* # 'ENTITY foo'
|
||||||
|
@ -68,8 +69,8 @@ re_match_field = re.compile(r"""
|
||||||
|
|
||||||
class Schema:
|
class Schema:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.entities = {}
|
self.entities = OrderedDict()
|
||||||
self.types = {}
|
self.types = OrderedDict()
|
||||||
|
|
||||||
class Entity:
|
class Entity:
|
||||||
def __init__(self,name,parent,members):
|
def __init__(self,name,parent,members):
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# List of IFC structures needed by Assimp
|
# List of IFC structures needed by Assimp
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# use genentitylist.sh to update this list
|
# use genentitylist.sh to update this list
|
||||||
|
|
||||||
# This machine-generated list is not complete, it lacks many intermediate
|
# This machine-generated list is not complete, it lacks many intermediate
|
||||||
# classes in the inheritance hierarchy. Those are magically augmented by the
|
# classes in the inheritance hierarchy. Those are magically augmented by the
|
||||||
# code generator. Also, the names of all used entities need to be present
|
# code generator. Also, the names of all used entities need to be present
|
||||||
# in the source code for this to work.
|
# in the source code for this to work.
|
||||||
|
|
||||||
IfcAnnotation
|
IfcAnnotation
|
||||||
IfcArbitraryClosedProfileDef
|
IfcArbitraryClosedProfileDef
|
||||||
IfcArbitraryOpenProfileDef
|
IfcArbitraryOpenProfileDef
|
||||||
|
IfcArbitraryProfileDefWithVoids
|
||||||
IfcAxis1Placement
|
IfcAxis1Placement
|
||||||
IfcAxis2Placement
|
IfcAxis2Placement
|
||||||
IfcAxis2Placement2D
|
IfcAxis2Placement2D
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,33 +0,0 @@
|
||||||
|
|
||||||
rem ------------------------------------------------------------------------------
|
|
||||||
rem Tiny script to execute a single unit test suite.
|
|
||||||
rem
|
|
||||||
rem Usage:
|
|
||||||
rem SET OUTDIR=<directory_for_test_results>
|
|
||||||
rem SET BINDIR=<directory_where_binaries_are_stored>
|
|
||||||
rem
|
|
||||||
rem CALL RunSingleUnitTestSuite <name_of_test> <output_file>
|
|
||||||
rem
|
|
||||||
rem Post:
|
|
||||||
rem FIRSTUTNA - if the test wasn't found, receives the test name
|
|
||||||
rem FIRSTUTFAILUR - if the test failed, receives the test name
|
|
||||||
rem
|
|
||||||
rem ------------------------------------------------------------------------------
|
|
||||||
IF NOT EXIST %BINDIR%\%1\unit.exe (
|
|
||||||
|
|
||||||
echo NOT AVAILABLE. Please rebuild this configuration
|
|
||||||
echo Unable to find %BINDIR%\%1\unit.exe > %OUTDIR%%2
|
|
||||||
SET FIRSTUTNA=%2
|
|
||||||
) ELSE (
|
|
||||||
|
|
||||||
%BINDIR%\%1\unit.exe > %OUTDIR%%2
|
|
||||||
IF errorlevel == 0 (
|
|
||||||
echo SUCCESS
|
|
||||||
) ELSE (
|
|
||||||
echo FAILURE, check output file: %2
|
|
||||||
SET FIRSTUTFAILURE=%2
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo.
|
|
|
@ -1,94 +0,0 @@
|
||||||
rem ------------------------------------------------------------------------------
|
|
||||||
rem Tiny script to execute Assimp's fully unit test suite for all configurations
|
|
||||||
rem
|
|
||||||
rem Usage: call RunUnitTestSuite
|
|
||||||
rem ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
rem Setup the console environment
|
|
||||||
set errorlevel=0
|
|
||||||
color 4e
|
|
||||||
cls
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
|
|
||||||
rem Setup target architecture
|
|
||||||
SET ARCHEXT=x64
|
|
||||||
IF %PROCESSOR_ARCHITECTURE% == x86 (
|
|
||||||
SET ARCHEXT=win32
|
|
||||||
)
|
|
||||||
|
|
||||||
rem Setup standard paths from here
|
|
||||||
SET OUTDIR=results\
|
|
||||||
SET BINDIR=..\bin\
|
|
||||||
SET FIRSTUTFAILURE=nil
|
|
||||||
SET FIRSTUTNA=nil
|
|
||||||
|
|
||||||
echo #=====================================================================
|
|
||||||
echo # Open Asset Import Library - Unittests
|
|
||||||
echo #=====================================================================
|
|
||||||
echo #
|
|
||||||
echo # Executes the Assimp library unit test suite for the following
|
|
||||||
echo # build configurations (if available):
|
|
||||||
echo #
|
|
||||||
echo # Release
|
|
||||||
echo # Release -st
|
|
||||||
echo # Release -noboost
|
|
||||||
echo # Release -dll
|
|
||||||
echo #
|
|
||||||
echo # Debug
|
|
||||||
echo # Debug -st
|
|
||||||
echo # Debug -noboost
|
|
||||||
echo # Debug -dll
|
|
||||||
echo ======================================================================
|
|
||||||
echo.
|
|
||||||
echo.
|
|
||||||
|
|
||||||
|
|
||||||
echo assimp-core release
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_release_%ARCHEXT% release.txt
|
|
||||||
|
|
||||||
echo assimp-core release -st
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_release-st_%ARCHEXT% release-st.txt
|
|
||||||
|
|
||||||
echo assimp-core release -noboost
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_release-noboost-st_%ARCHEXT% release-st-noboost.txt
|
|
||||||
|
|
||||||
echo assimp-core release -dll
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_release-dll_%ARCHEXT% release-dll.txt
|
|
||||||
|
|
||||||
echo assimp-core debug
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_debug_%ARCHEXT% debug.txt
|
|
||||||
|
|
||||||
echo assimp-core debug -st
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_debug-st_%ARCHEXT% debug-st.txt
|
|
||||||
|
|
||||||
echo assimp-core debug -noboost
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_debug-noboost-st_%ARCHEXT% debug-st-noboost.txt
|
|
||||||
|
|
||||||
echo assimp-core debug -dll
|
|
||||||
echo **********************************************************************
|
|
||||||
call RunSingleUnitTestSuite unit_debug-dll_%ARCHEXT% debug-dll.txt
|
|
||||||
|
|
||||||
|
|
||||||
echo ======================================================================
|
|
||||||
IF %FIRSTUTNA% == nil (
|
|
||||||
echo All test configs have been found.
|
|
||||||
) ELSE (
|
|
||||||
echo One or more test configs are not available.
|
|
||||||
)
|
|
||||||
|
|
||||||
IF %FIRSTUTFAILURE% == nil (
|
|
||||||
echo All tests have been successful.
|
|
||||||
) ELSE (
|
|
||||||
echo One or more tests failed.
|
|
||||||
)
|
|
||||||
echo.
|
|
||||||
|
|
||||||
pause
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,754 @@
|
||||||
|
ply
|
||||||
|
format ascii 1.0
|
||||||
|
element vertex 486
|
||||||
|
property float32 x
|
||||||
|
property float32 y
|
||||||
|
property float32 z
|
||||||
|
element face 912
|
||||||
|
property list uint8 int32 vertex_indices
|
||||||
|
end_header
|
||||||
|
-1.106 3.844 9.073
|
||||||
|
-0.3523 0.4402 11.07
|
||||||
|
1.028 3.76 9.209
|
||||||
|
0.137 -0.5632 10.73
|
||||||
|
2.01 4.503 5.887
|
||||||
|
0.07813 5.232 6.794
|
||||||
|
-0.7266 3.741 3.839
|
||||||
|
-2.789 3.179 5.07
|
||||||
|
-0.9185 2.402 3.279
|
||||||
|
1.445 2.139 3.394
|
||||||
|
-3.114 1.498 5.285
|
||||||
|
-1.317 -1.269 8.385
|
||||||
|
-0.854 -1.319 5.036
|
||||||
|
-0.9351 5.347 0.6162
|
||||||
|
-0.8184 2.622 3.235
|
||||||
|
0.4875 5.529 -0.2241
|
||||||
|
3.193 2.756 1.633
|
||||||
|
3.213 1.145 -2.568
|
||||||
|
-2.25 1.208 2.767
|
||||||
|
0.3225 0.8339 3.323
|
||||||
|
1.354 -1.725 1.105
|
||||||
|
0.1887 1.133 -5.785
|
||||||
|
-3.637 2.696 0.3325
|
||||||
|
-3.706 0.8936 -0.5452
|
||||||
|
-0.4326 -0.8737 -4.095
|
||||||
|
-2.994 -0.4858 0.9023
|
||||||
|
0.1252 -2.079 -1.51
|
||||||
|
2.856 -0.7459 -1.187
|
||||||
|
2.32 3.733 8.13
|
||||||
|
2.031 3.721 9.095
|
||||||
|
2.819 3.567 8.537
|
||||||
|
1.994 2.581 9.711
|
||||||
|
2.64 2.491 9.542
|
||||||
|
3.187 2.528 8.375
|
||||||
|
1.628 2.491 7.518
|
||||||
|
1.62 3.721 8.274
|
||||||
|
0.9868 2.471 8.914
|
||||||
|
1.552 2.106 9.414
|
||||||
|
2.657 1.774 8.918
|
||||||
|
-1.805 3.733 8.13
|
||||||
|
-2.094 3.721 9.095
|
||||||
|
-1.306 3.567 8.537
|
||||||
|
-2.131 2.581 9.711
|
||||||
|
-1.485 2.491 9.542
|
||||||
|
-0.938 2.528 8.375
|
||||||
|
-2.497 2.491 7.518
|
||||||
|
-2.505 3.721 8.274
|
||||||
|
-3.138 2.471 8.914
|
||||||
|
-2.573 2.106 9.414
|
||||||
|
-1.469 1.774 8.918
|
||||||
|
1.549 3.638 6.803
|
||||||
|
1.355 3.638 6.7
|
||||||
|
1.424 5.126 6.883
|
||||||
|
1.615 5.083 6.981
|
||||||
|
1.169 3.638 6.815
|
||||||
|
1.237 5.115 6.997
|
||||||
|
1.176 3.638 7.035
|
||||||
|
1.241 5.061 7.21
|
||||||
|
1.369 3.638 7.138
|
||||||
|
1.433 5.018 7.308
|
||||||
|
1.556 3.638 7.023
|
||||||
|
1.62 5.029 7.194
|
||||||
|
1.625 6.512 7.421
|
||||||
|
1.811 6.429 7.504
|
||||||
|
1.437 6.49 7.531
|
||||||
|
1.434 6.386 7.724
|
||||||
|
1.619 6.304 7.807
|
||||||
|
1.808 6.326 7.697
|
||||||
|
1.945 7.702 8.276
|
||||||
|
2.121 7.585 8.335
|
||||||
|
1.754 7.672 8.38
|
||||||
|
1.74 7.525 8.542
|
||||||
|
1.916 7.408 8.601
|
||||||
|
2.107 7.439 8.497
|
||||||
|
2.362 8.615 9.391
|
||||||
|
2.526 8.473 9.417
|
||||||
|
2.168 8.578 9.487
|
||||||
|
2.138 8.398 9.608
|
||||||
|
2.303 8.255 9.635
|
||||||
|
2.497 8.293 9.539
|
||||||
|
2.847 9.189 10.69
|
||||||
|
2.998 9.03 10.68
|
||||||
|
2.649 9.148 10.78
|
||||||
|
2.603 8.947 10.85
|
||||||
|
2.753 8.788 10.84
|
||||||
|
2.95 8.83 10.75
|
||||||
|
3.368 9.385 12.08
|
||||||
|
3.503 9.22 12.03
|
||||||
|
3.167 9.342 12.16
|
||||||
|
3.101 9.134 12.18
|
||||||
|
3.236 8.97 12.13
|
||||||
|
3.438 9.013 12.06
|
||||||
|
3.889 9.189 13.48
|
||||||
|
4.01 9.03 13.39
|
||||||
|
3.684 9.148 13.54
|
||||||
|
3.599 8.947 13.51
|
||||||
|
3.719 8.788 13.42
|
||||||
|
3.925 8.83 13.36
|
||||||
|
4.374 8.615 14.77
|
||||||
|
4.481 8.473 14.65
|
||||||
|
4.165 8.578 14.83
|
||||||
|
4.063 8.398 14.76
|
||||||
|
4.17 8.255 14.63
|
||||||
|
4.379 8.293 14.57
|
||||||
|
4.791 7.702 15.89
|
||||||
|
4.886 7.585 15.73
|
||||||
|
4.579 7.672 15.94
|
||||||
|
4.462 7.525 15.82
|
||||||
|
4.556 7.408 15.66
|
||||||
|
4.769 7.439 15.62
|
||||||
|
5.111 6.512 16.74
|
||||||
|
5.196 6.429 16.56
|
||||||
|
4.896 6.49 16.78
|
||||||
|
4.768 6.386 16.64
|
||||||
|
4.853 6.304 16.46
|
||||||
|
5.068 6.326 16.42
|
||||||
|
-1.141 5.126 6.883
|
||||||
|
-1.072 3.638 6.7
|
||||||
|
-1.266 3.638 6.803
|
||||||
|
-1.332 5.083 6.981
|
||||||
|
-0.9541 5.115 6.997
|
||||||
|
-0.886 3.638 6.815
|
||||||
|
-0.9585 5.061 7.21
|
||||||
|
-0.8928 3.638 7.035
|
||||||
|
-1.15 5.018 7.308
|
||||||
|
-1.086 3.638 7.138
|
||||||
|
-1.337 5.029 7.194
|
||||||
|
-1.272 3.638 7.023
|
||||||
|
-1.342 6.512 7.421
|
||||||
|
-1.528 6.429 7.504
|
||||||
|
-1.154 6.49 7.531
|
||||||
|
-1.151 6.386 7.724
|
||||||
|
-1.336 6.304 7.807
|
||||||
|
-1.525 6.326 7.697
|
||||||
|
-1.662 7.702 8.276
|
||||||
|
-1.838 7.585 8.335
|
||||||
|
-1.471 7.672 8.38
|
||||||
|
-1.457 7.525 8.542
|
||||||
|
-1.633 7.408 8.601
|
||||||
|
-1.824 7.439 8.497
|
||||||
|
-2.079 8.615 9.391
|
||||||
|
-2.243 8.473 9.417
|
||||||
|
-1.885 8.578 9.487
|
||||||
|
-1.855 8.398 9.608
|
||||||
|
-2.02 8.255 9.635
|
||||||
|
-2.214 8.293 9.539
|
||||||
|
-2.564 9.189 10.69
|
||||||
|
-2.715 9.03 10.68
|
||||||
|
-2.366 9.148 10.78
|
||||||
|
-2.32 8.947 10.85
|
||||||
|
-2.47 8.788 10.84
|
||||||
|
-2.667 8.83 10.75
|
||||||
|
-3.085 9.385 12.08
|
||||||
|
-3.22 9.22 12.03
|
||||||
|
-2.884 9.342 12.16
|
||||||
|
-2.818 9.134 12.18
|
||||||
|
-2.953 8.97 12.13
|
||||||
|
-3.155 9.013 12.06
|
||||||
|
-3.606 9.189 13.48
|
||||||
|
-3.726 9.03 13.39
|
||||||
|
-3.4 9.148 13.54
|
||||||
|
-3.316 8.947 13.51
|
||||||
|
-3.437 8.788 13.42
|
||||||
|
-3.642 8.83 13.36
|
||||||
|
-4.091 8.615 14.77
|
||||||
|
-4.198 8.473 14.65
|
||||||
|
-3.882 8.578 14.83
|
||||||
|
-3.78 8.398 14.76
|
||||||
|
-3.887 8.255 14.63
|
||||||
|
-4.096 8.293 14.57
|
||||||
|
-4.508 7.702 15.89
|
||||||
|
-4.603 7.585 15.73
|
||||||
|
-4.296 7.672 15.94
|
||||||
|
-4.179 7.525 15.82
|
||||||
|
-4.273 7.408 15.66
|
||||||
|
-4.485 7.439 15.62
|
||||||
|
-4.828 6.512 16.74
|
||||||
|
-4.913 6.429 16.56
|
||||||
|
-4.613 6.49 16.78
|
||||||
|
-4.484 6.386 16.64
|
||||||
|
-4.57 6.304 16.46
|
||||||
|
-4.784 6.326 16.42
|
||||||
|
-1.519 -2.27 2.989
|
||||||
|
-1.987 -1.082 3.408
|
||||||
|
-2.709 -1.989 3.536
|
||||||
|
-1.513 -2.259 2.974
|
||||||
|
-2.524 -1.536 2.471
|
||||||
|
-4.318 -0.3933 4.187
|
||||||
|
-4.692 -0.6204 3.123
|
||||||
|
-6.274 0.9227 4.173
|
||||||
|
-5.533 1.852 4.043
|
||||||
|
-6.084 1.387 3.082
|
||||||
|
-6.844 2.279 4.015
|
||||||
|
-6.83 1.957 4.012
|
||||||
|
-6.886 2.118 3.737
|
||||||
|
-7.536 1.346 4.658
|
||||||
|
-7.229 0.9683 4.298
|
||||||
|
-8.053 1.724 3.821
|
||||||
|
-7.747 1.346 3.46
|
||||||
|
-9.085 -0.1982 5.078
|
||||||
|
-9.347 -0.1982 3.597
|
||||||
|
-8.702 -0.7393 4.247
|
||||||
|
-10.91 -1.528 5.154
|
||||||
|
-10.39 -2.11 4.847
|
||||||
|
-11.08 -1.528 4.148
|
||||||
|
-10.49 -2.11 4.26
|
||||||
|
-11.58 -2.509 4.768
|
||||||
|
-11.57 -2.523 4.76
|
||||||
|
-11.59 -2.509 4.742
|
||||||
|
-11.57 -2.523 4.744
|
||||||
|
-12.39 -3.546 5.269
|
||||||
|
-11.93 -3.852 5.034
|
||||||
|
-12.52 -3.546 4.548
|
||||||
|
-12.87 -4.803 5.622
|
||||||
|
-12.58 -5.09 4.606
|
||||||
|
-13.49 -4.516 4.767
|
||||||
|
-13.11 -6.264 5.38
|
||||||
|
-14.78 -6.803 5.643
|
||||||
|
-14.49 -7.092 4.622
|
||||||
|
-15.35 -8.042 5.637
|
||||||
|
-14.73 -8.43 5.528
|
||||||
|
-15.15 -8.236 4.95
|
||||||
|
-15.78 -9.378 5.503
|
||||||
|
-15.77 -9.385 5.497
|
||||||
|
-15.78 -9.375 5.495
|
||||||
|
-15.78 -9.378 5.486
|
||||||
|
-15.77 -9.383 5.484
|
||||||
|
-1.522 -2.262 -1.24
|
||||||
|
-1.519 -2.258 -1.231
|
||||||
|
-1.522 -2.262 -1.222
|
||||||
|
-1.529 -2.27 -1.222
|
||||||
|
-1.529 -2.27 -1.24
|
||||||
|
-2.061 -1.082 -0.8906
|
||||||
|
-2.428 -1.536 -1.907
|
||||||
|
-3.082 -0.4963 -0.5522
|
||||||
|
-3.082 -0.4963 -1.91
|
||||||
|
-3.759 -1.333 -1.628
|
||||||
|
-5.567 0.1257 -0.8323
|
||||||
|
-5.665 1.852 -0.8818
|
||||||
|
-6.417 0.9227 -0.8818
|
||||||
|
-6.041 1.387 -1.924
|
||||||
|
-6.95 2.279 -1.137
|
||||||
|
-6.937 1.957 -1.326
|
||||||
|
-6.943 2.118 -1.418
|
||||||
|
-7.378 0.9683 -0.9246
|
||||||
|
-8.108 1.724 -0.9246
|
||||||
|
-7.743 1.346 -1.84
|
||||||
|
-8.797 0.8371 -0.6052
|
||||||
|
-9.793 0.269 -1.611
|
||||||
|
-8.891 -0.6654 -1.611
|
||||||
|
-10.59 -2.11 -0.9326
|
||||||
|
-10.57 -0.523 -0.8679
|
||||||
|
-11.3 -1.375 -0.9326
|
||||||
|
-10.94 -1.742 -1.823
|
||||||
|
-11.75 -2.506 -1.223
|
||||||
|
-11.73 -2.523 -1.223
|
||||||
|
-11.74 -2.514 -1.247
|
||||||
|
-12.76 -3.466 -1.017
|
||||||
|
-12.14 -3.852 -1.017
|
||||||
|
-12.45 -3.659 -1.656
|
||||||
|
-13.16 -4.803 -0.6001
|
||||||
|
-12.7 -5.09 -1.55
|
||||||
|
-13.62 -4.516 -1.55
|
||||||
|
-13.36 -6.264 -0.8809
|
||||||
|
-15.05 -6.803 -0.9114
|
||||||
|
-14.58 -7.092 -1.866
|
||||||
|
-15.6 -8.042 -1.016
|
||||||
|
-14.98 -8.43 -1.016
|
||||||
|
-15.29 -8.236 -1.658
|
||||||
|
-16.01 -9.378 -1.222
|
||||||
|
-15.99 -9.385 -1.226
|
||||||
|
-16.01 -9.375 -1.231
|
||||||
|
-16.01 -9.378 -1.24
|
||||||
|
-16 -9.383 -1.24
|
||||||
|
-1.522 -2.27 -4.918
|
||||||
|
-2.105 -1.082 -4.684
|
||||||
|
-2.827 -1.989 -4.812
|
||||||
|
-1.513 -2.262 -4.935
|
||||||
|
-2.29 -1.536 -5.749
|
||||||
|
-4.562 -0.3933 -4.75
|
||||||
|
-4.55 -0.6204 -5.878
|
||||||
|
-6.395 0.9227 -5.432
|
||||||
|
-5.655 1.852 -5.302
|
||||||
|
-5.844 1.387 -6.393
|
||||||
|
-6.877 2.279 -5.776
|
||||||
|
-6.863 1.957 -5.773
|
||||||
|
-6.821 2.118 -6.051
|
||||||
|
-7.747 1.346 -5.408
|
||||||
|
-7.335 0.9683 -5.641
|
||||||
|
-7.947 1.724 -6.372
|
||||||
|
-7.536 1.346 -6.605
|
||||||
|
-9.347 -0.1982 -5.543
|
||||||
|
-9.085 -0.1982 -7.025
|
||||||
|
-8.702 -0.7393 -6.193
|
||||||
|
-11.08 -1.528 -6.095
|
||||||
|
-10.49 -2.11 -6.206
|
||||||
|
-10.91 -1.528 -7.101
|
||||||
|
-10.39 -2.11 -6.794
|
||||||
|
-11.59 -2.509 -6.689
|
||||||
|
-11.57 -2.523 -6.691
|
||||||
|
-11.58 -2.509 -6.715
|
||||||
|
-11.57 -2.523 -6.707
|
||||||
|
-12.52 -3.546 -6.495
|
||||||
|
-12.01 -3.852 -6.559
|
||||||
|
-12.39 -3.546 -7.217
|
||||||
|
-13.09 -4.803 -6.326
|
||||||
|
-12.47 -5.09 -7.18
|
||||||
|
-13.38 -4.516 -7.341
|
||||||
|
-13.24 -6.264 -6.637
|
||||||
|
-14.89 -6.803 -6.96
|
||||||
|
-14.27 -7.092 -7.819
|
||||||
|
-15.42 -8.042 -7.159
|
||||||
|
-14.8 -8.43 -7.051
|
||||||
|
-15 -8.236 -7.738
|
||||||
|
-15.78 -9.378 -7.432
|
||||||
|
-15.77 -9.385 -7.434
|
||||||
|
-15.78 -9.375 -7.442
|
||||||
|
-15.78 -9.378 -7.45
|
||||||
|
-15.77 -9.383 -7.448
|
||||||
|
1.522 -2.27 -4.918
|
||||||
|
1.511 -2.258 -4.926
|
||||||
|
1.513 -2.262 -4.935
|
||||||
|
2.828 -1.989 -4.812
|
||||||
|
2.105 -1.082 -4.684
|
||||||
|
2.29 -1.536 -5.749
|
||||||
|
4.55 -0.6204 -5.878
|
||||||
|
4.562 -0.3933 -4.75
|
||||||
|
6.395 0.9227 -5.432
|
||||||
|
5.655 1.852 -5.302
|
||||||
|
5.844 1.387 -6.393
|
||||||
|
6.877 2.279 -5.776
|
||||||
|
6.863 1.957 -5.773
|
||||||
|
6.821 2.118 -6.051
|
||||||
|
7.335 0.9683 -5.641
|
||||||
|
7.747 1.346 -5.408
|
||||||
|
7.947 1.724 -6.372
|
||||||
|
7.536 1.346 -6.605
|
||||||
|
9.347 -0.1982 -5.543
|
||||||
|
9.086 -0.1982 -7.025
|
||||||
|
8.702 -0.7393 -6.193
|
||||||
|
11.08 -1.528 -6.095
|
||||||
|
10.49 -2.11 -6.206
|
||||||
|
10.91 -1.528 -7.101
|
||||||
|
10.39 -2.11 -6.794
|
||||||
|
11.59 -2.509 -6.689
|
||||||
|
11.57 -2.523 -6.691
|
||||||
|
11.58 -2.509 -6.715
|
||||||
|
11.57 -2.523 -6.707
|
||||||
|
12.52 -3.546 -6.495
|
||||||
|
12.01 -3.852 -6.559
|
||||||
|
12.39 -3.546 -7.217
|
||||||
|
12.47 -5.09 -7.18
|
||||||
|
13.09 -4.803 -6.326
|
||||||
|
13.38 -4.516 -7.341
|
||||||
|
13.24 -6.264 -6.637
|
||||||
|
14.89 -6.803 -6.96
|
||||||
|
14.27 -7.092 -7.819
|
||||||
|
15.42 -8.042 -7.159
|
||||||
|
14.8 -8.43 -7.051
|
||||||
|
15 -8.236 -7.738
|
||||||
|
15.78 -9.378 -7.432
|
||||||
|
15.77 -9.385 -7.434
|
||||||
|
15.78 -9.375 -7.442
|
||||||
|
15.78 -9.378 -7.45
|
||||||
|
15.77 -9.383 -7.448
|
||||||
|
-0.9592 -0.9547 10.35
|
||||||
|
0.007813 0.3928 11.6
|
||||||
|
-0.7324 1.062 10.63
|
||||||
|
0.007813 -1.855 11.37
|
||||||
|
0.007813 -2.459 10.63
|
||||||
|
0.007813 0.3928 9.662
|
||||||
|
-0.3928 1.509 10.63
|
||||||
|
0.7327 1.062 10.63
|
||||||
|
-0.007813 0.3928 11.6
|
||||||
|
0.9595 -0.9547 10.35
|
||||||
|
-0.007813 -1.855 11.37
|
||||||
|
-0.007813 -2.459 10.63
|
||||||
|
-0.007813 0.3928 9.662
|
||||||
|
0.3931 1.509 10.63
|
||||||
|
1.513 -2.262 2.988
|
||||||
|
1.511 -2.258 2.979
|
||||||
|
1.516 -2.262 2.97
|
||||||
|
1.522 -2.27 2.971
|
||||||
|
1.52 -2.27 2.989
|
||||||
|
1.987 -1.082 3.408
|
||||||
|
2.524 -1.536 2.471
|
||||||
|
2.933 -0.4963 3.919
|
||||||
|
3.168 -0.4963 2.581
|
||||||
|
3.786 -1.333 2.977
|
||||||
|
5.429 0.1257 4.074
|
||||||
|
5.534 1.852 4.042
|
||||||
|
6.274 0.9227 4.173
|
||||||
|
6.085 1.387 3.082
|
||||||
|
6.863 1.957 3.827
|
||||||
|
6.844 2.279 4.015
|
||||||
|
6.886 2.118 3.737
|
||||||
|
7.229 0.9683 4.298
|
||||||
|
7.947 1.724 4.425
|
||||||
|
7.747 1.346 3.46
|
||||||
|
8.57 0.8371 4.859
|
||||||
|
9.726 0.269 4.042
|
||||||
|
8.838 -0.6654 3.885
|
||||||
|
10.39 -2.11 4.847
|
||||||
|
10.37 -0.523 4.909
|
||||||
|
11.09 -1.375 4.97
|
||||||
|
10.89 -1.742 4.032
|
||||||
|
11.59 -2.506 4.763
|
||||||
|
11.57 -2.523 4.76
|
||||||
|
11.58 -2.514 4.739
|
||||||
|
12.55 -3.466 5.142
|
||||||
|
11.93 -3.852 5.034
|
||||||
|
12.35 -3.659 4.459
|
||||||
|
12.58 -5.09 4.606
|
||||||
|
12.87 -4.803 5.622
|
||||||
|
13.49 -4.516 4.767
|
||||||
|
13.11 -6.264 5.38
|
||||||
|
14.78 -6.803 5.643
|
||||||
|
14.49 -7.092 4.622
|
||||||
|
15.35 -8.042 5.637
|
||||||
|
14.73 -8.43 5.528
|
||||||
|
15.15 -8.236 4.95
|
||||||
|
15.78 -9.378 5.503
|
||||||
|
15.77 -9.385 5.497
|
||||||
|
15.78 -9.375 5.495
|
||||||
|
15.78 -9.378 5.486
|
||||||
|
15.77 -9.383 5.484
|
||||||
|
1.529 -2.27 -1.222
|
||||||
|
1.519 -2.258 -1.231
|
||||||
|
1.522 -2.262 -1.24
|
||||||
|
2.795 -1.989 -0.8906
|
||||||
|
2.062 -1.082 -0.8906
|
||||||
|
2.428 -1.536 -1.907
|
||||||
|
4.677 -0.6204 -1.642
|
||||||
|
4.493 -0.3933 -0.5283
|
||||||
|
6.417 0.9227 -0.8818
|
||||||
|
5.665 1.852 -0.8818
|
||||||
|
6.041 1.387 -1.924
|
||||||
|
6.951 2.279 -1.137
|
||||||
|
6.937 1.957 -1.137
|
||||||
|
6.944 2.118 -1.418
|
||||||
|
7.379 0.9683 -0.9246
|
||||||
|
7.743 1.346 -0.623
|
||||||
|
8.108 1.724 -1.538
|
||||||
|
7.743 1.346 -1.84
|
||||||
|
9.343 -0.1982 -0.4792
|
||||||
|
9.343 -0.1982 -1.983
|
||||||
|
8.82 -0.7393 -1.231
|
||||||
|
11.15 -1.528 -0.7207
|
||||||
|
10.59 -2.11 -0.9326
|
||||||
|
11.15 -1.528 -1.742
|
||||||
|
10.59 -2.11 -1.53
|
||||||
|
11.75 -2.509 -1.218
|
||||||
|
11.73 -2.523 -1.223
|
||||||
|
11.75 -2.509 -1.245
|
||||||
|
11.73 -2.523 -1.239
|
||||||
|
12.63 -3.546 -0.8647
|
||||||
|
12.14 -3.852 -1.017
|
||||||
|
12.63 -3.546 -1.598
|
||||||
|
12.7 -5.09 -1.55
|
||||||
|
13.16 -4.803 -0.6001
|
||||||
|
13.62 -4.516 -1.55
|
||||||
|
13.36 -6.264 -0.8804
|
||||||
|
15.05 -6.803 -0.9111
|
||||||
|
14.58 -7.092 -1.866
|
||||||
|
15.6 -8.042 -1.016
|
||||||
|
14.98 -8.43 -1.016
|
||||||
|
15.29 -8.236 -1.658
|
||||||
|
16.01 -9.378 -1.222
|
||||||
|
15.99 -9.385 -1.226
|
||||||
|
16.01 -9.375 -1.231
|
||||||
|
16.01 -9.378 -1.24
|
||||||
|
16 -9.383 -1.24
|
||||||
|
-0.7932 4.462 -7.734
|
||||||
|
-0.3843 1.974 -5.495
|
||||||
|
1.95 3.241 -7.348
|
||||||
|
1.167 0.6428 -6.109
|
||||||
|
3.808 0.1871 -9.572
|
||||||
|
3.644 1.688 -11.88
|
||||||
|
0.07617 4.961 -10.12
|
||||||
|
3.28 -0.5704 -14.15
|
||||||
|
0.2488 -1.848 -16.78
|
||||||
|
-0.9744 -2.686 -16.57
|
||||||
|
0.7307 -3.159 -16.47
|
||||||
|
-2.678 2.963 -8.185
|
||||||
|
-2.616 -2.779 -12.24
|
||||||
|
-1.159 -1.533 -8.922
|
||||||
|
3 0 1 2
|
||||||
|
3 1 3 2
|
||||||
|
3 2 4 5
|
||||||
|
3 4 6 5
|
||||||
|
3 5 6 7
|
||||||
|
3 7 6 8
|
||||||
|
3 2 3 9
|
||||||
|
3 2 9 4
|
||||||
|
3 4 9 6
|
||||||
|
3 6 9 8
|
||||||
|
3 5 0 2
|
||||||
|
3 5 7 0
|
||||||
|
3 8 10 7
|
||||||
|
3 7 10 0
|
||||||
|
3 0 10 1
|
||||||
|
3 1 10 11
|
||||||
|
3 1 11 3
|
||||||
|
3 10 12 11
|
||||||
|
3 11 12 3
|
||||||
|
3 3 12 9
|
||||||
|
3 10 8 12
|
||||||
|
3 12 8 9
|
||||||
|
3 13 14 15
|
||||||
|
3 15 14 16
|
||||||
|
3 17 15 16
|
||||||
|
3 18 19 14
|
||||||
|
3 14 19 16
|
||||||
|
3 19 20 16
|
||||||
|
3 15 17 21
|
||||||
|
3 15 21 13
|
||||||
|
3 14 13 18
|
||||||
|
3 21 22 13
|
||||||
|
3 13 22 18
|
||||||
|
3 21 23 22
|
||||||
|
3 21 24 23
|
||||||
|
3 23 25 22
|
||||||
|
3 22 25 18
|
||||||
|
3 18 25 20
|
||||||
|
3 18 20 19
|
||||||
|
3 23 26 25
|
||||||
|
3 25 26 20
|
||||||
|
3 23 24 26
|
||||||
|
3 26 24 27
|
||||||
|
3 26 27 20
|
||||||
|
3 20 27 16
|
||||||
|
3 24 21 27
|
||||||
|
3 27 21 17
|
||||||
|
3 27 17 16
|
||||||
|
3 28 29 30
|
||||||
|
3 31 32 29
|
||||||
|
3 29 32 30
|
||||||
|
3 32 33 30
|
||||||
|
3 30 33 28
|
||||||
|
3 28 33 34
|
||||||
|
3 28 34 35
|
||||||
|
3 35 34 36
|
||||||
|
3 28 35 29
|
||||||
|
3 35 36 29
|
||||||
|
3 29 36 31
|
||||||
|
3 36 37 31
|
||||||
|
3 31 37 32
|
||||||
|
3 37 38 32
|
||||||
|
3 32 38 33
|
||||||
|
3 36 34 37
|
||||||
|
3 37 34 38
|
||||||
|
3 38 34 33
|
||||||
|
3 39 40 41
|
||||||
|
3 42 43 40
|
||||||
|
3 40 43 41
|
||||||
|
3 43 44 41
|
||||||
|
3 41 44 39
|
||||||
|
3 39 44 45
|
||||||
|
3 39 45 46
|
||||||
|
3 46 45 47
|
||||||
|
3 39 46 40
|
||||||
|
3 46 47 40
|
||||||
|
3 40 47 42
|
||||||
|
3 47 48 42
|
||||||
|
3 42 48 43
|
||||||
|
3 48 49 43
|
||||||
|
3 43 49 44
|
||||||
|
3 47 45 48
|
||||||
|
3 48 45 49
|
||||||
|
3 49 45 44
|
||||||
|
3 50 51 52
|
||||||
|
3 50 52 53
|
||||||
|
3 51 54 55
|
||||||
|
3 51 55 52
|
||||||
|
3 54 56 57
|
||||||
|
3 54 57 55
|
||||||
|
3 56 58 59
|
||||||
|
3 56 59 57
|
||||||
|
3 58 60 61
|
||||||
|
3 58 61 59
|
||||||
|
3 60 50 53
|
||||||
|
3 60 53 61
|
||||||
|
3 53 52 62
|
||||||
|
3 53 62 63
|
||||||
|
3 52 55 64
|
||||||
|
3 52 64 62
|
||||||
|
3 55 57 65
|
||||||
|
3 55 65 64
|
||||||
|
3 57 59 66
|
||||||
|
3 57 66 65
|
||||||
|
3 59 61 67
|
||||||
|
3 59 67 66
|
||||||
|
3 61 53 63
|
||||||
|
3 61 63 67
|
||||||
|
3 63 62 68
|
||||||
|
3 63 68 69
|
||||||
|
3 62 64 70
|
||||||
|
3 62 70 68
|
||||||
|
3 64 65 71
|
||||||
|
3 64 71 70
|
||||||
|
3 65 66 72
|
||||||
|
3 65 72 71
|
||||||
|
3 66 67 73
|
||||||
|
3 66 73 72
|
||||||
|
3 67 63 69
|
||||||
|
3 67 69 73
|
||||||
|
3 69 68 74
|
||||||
|
3 69 74 75
|
||||||
|
3 68 70 76
|
||||||
|
3 68 76 74
|
||||||
|
3 70 71 77
|
||||||
|
3 70 77 76
|
||||||
|
3 71 72 78
|
||||||
|
3 71 78 77
|
||||||
|
3 72 73 79
|
||||||
|
3 72 79 78
|
||||||
|
3 73 69 75
|
||||||
|
3 73 75 79
|
||||||
|
3 75 74 80
|
||||||
|
3 75 80 81
|
||||||
|
3 74 76 82
|
||||||
|
3 74 82 80
|
||||||
|
3 76 77 83
|
||||||
|
3 76 83 82
|
||||||
|
3 77 78 84
|
||||||
|
3 77 84 83
|
||||||
|
3 78 79 85
|
||||||
|
3 78 85 84
|
||||||
|
3 79 75 81
|
||||||
|
3 79 81 85
|
||||||
|
3 81 80 86
|
||||||
|
3 81 86 87
|
||||||
|
3 80 82 88
|
||||||
|
3 80 88 86
|
||||||
|
3 82 83 89
|
||||||
|
3 82 89 88
|
||||||
|
3 83 84 90
|
||||||
|
3 83 90 89
|
||||||
|
3 84 85 91
|
||||||
|
3 84 91 90
|
||||||
|
3 85 81 87
|
||||||
|
3 85 87 91
|
||||||
|
3 87 86 92
|
||||||
|
3 87 92 93
|
||||||
|
3 86 88 94
|
||||||
|
3 86 94 92
|
||||||
|
3 88 89 95
|
||||||
|
3 88 95 94
|
||||||
|
3 89 90 96
|
||||||
|
3 89 96 95
|
||||||
|
3 90 91 97
|
||||||
|
3 90 97 96
|
||||||
|
3 91 87 93
|
||||||
|
3 91 93 97
|
||||||
|
3 93 92 98
|
||||||
|
3 93 98 99
|
||||||
|
3 92 94 100
|
||||||
|
3 92 100 98
|
||||||
|
3 94 95 101
|
||||||
|
3 94 101 100
|
||||||
|
3 95 96 102
|
||||||
|
3 95 102 101
|
||||||
|
3 96 97 103
|
||||||
|
3 96 103 102
|
||||||
|
3 97 93 99
|
||||||
|
3 97 99 103
|
||||||
|
3 99 98 104
|
||||||
|
3 99 104 105
|
||||||
|
3 98 100 106
|
||||||
|
3 98 106 104
|
||||||
|
3 100 101 107
|
||||||
|
3 100 107 106
|
||||||
|
3 101 102 108
|
||||||
|
3 101 108 107
|
||||||
|
3 102 103 109
|
||||||
|
3 102 109 108
|
||||||
|
3 103 99 105
|
||||||
|
3 103 105 109
|
||||||
|
3 105 104 110
|
||||||
|
3 105 110 111
|
||||||
|
3 104 106 112
|
||||||
|
3 104 112 110
|
||||||
|
3 106 107 113
|
||||||
|
3 106 113 112
|
||||||
|
3 107 108 114
|
||||||
|
3 107 114 113
|
||||||
|
3 108 109 115
|
||||||
|
3 108 115 114
|
||||||
|
3 109 105 111
|
||||||
|
3 109 111 115
|
||||||
|
3 54 51 50
|
||||||
|
3 56 54 50
|
||||||
|
3 58 56 50
|
||||||
|
3 60 58 50
|
||||||
|
3 112 113 110
|
||||||
|
3 113 114 110
|
||||||
|
3 114 115 110
|
||||||
|
3 115 111 110
|
||||||
|
3 116 117 118
|
||||||
|
3 119 116 118
|
||||||
|
3 120 121 117
|
||||||
|
3 116 120 117
|
||||||
|
3 122 123 121
|
||||||
|
3 120 122 121
|
||||||
|
3 124 125 123
|
||||||
|
3 122 124 123
|
||||||
|
3 126 127 125
|
||||||
|
3 124 126 125
|
||||||
|
3 119 118 127
|
||||||
|
3 126 119 127
|
||||||
|
3 128 116 119
|
||||||
|
3 129 128 119
|
||||||
|
3 130 120 116
|
||||||
|
3 128 130 116
|
||||||
|
3 131 122 120
|
||||||
|
3 130 131 120
|
||||||
|
3 132 124 122
|
||||||
|
3 131 132 122
|
||||||
|
3 133 126 124
|
||||||
|
3 132 133 124
|
||||||
|
3 129 119 126
|
||||||
|
3 133 129 126
|
||||||
|
3 134 128 129
|
||||||
|
3 135 134 129
|
||||||
|
3 136 130 128
|
||||||
|
3 134 136 128
|
||||||
|
3 137 131 130
|
||||||
|
3 136 137 130
|
||||||
|
3 138 132 131
|
||||||
|
3 137 138 131
|
||||||
|
3 139 133 132
|
||||||
|
3 138 139 132
|
||||||
|
3 135 129 133
|
||||||
|
3 139 135 133
|
||||||
|
3 140 134 135
|
||||||
|
3 141 140 135
|
||||||
|
3 142 136 134
|
||||||
|
3 140 142 134
|
||||||
|
3 143 137 136
|
||||||
|
3 142 143 136
|
||||||
|
3 144 138 137
|
||||||
|
3 143 144 137
|
||||||
|
3 145 139 138
|
||||||
|
3 144 145 138
|
||||||
|
3 141 135 139
|
|
@ -0,0 +1,165 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,95 @@
|
||||||
|
Metric (key = "distance") {float {1}}
|
||||||
|
Metric (key = "angle") {float {1}}
|
||||||
|
Metric (key = "time") {float {1}}
|
||||||
|
Metric (key = "up") {string {"z"}}
|
||||||
|
|
||||||
|
GeometryNode $node1
|
||||||
|
{
|
||||||
|
Name {string {"Box001"}}
|
||||||
|
ObjectRef {ref {$geometry1}}
|
||||||
|
MaterialRef {ref {$material1}}
|
||||||
|
|
||||||
|
Transform
|
||||||
|
{
|
||||||
|
float[16]
|
||||||
|
{
|
||||||
|
{0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0
|
||||||
|
0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0
|
||||||
|
0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0
|
||||||
|
0xBEF33B00, 0x411804DE, 0x00000000, 0x3F800000} // -0.47506, 9.50119, 0, 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryNode $node2
|
||||||
|
{
|
||||||
|
Name {string {"Box002"}}
|
||||||
|
ObjectRef {ref {$geometry1}}
|
||||||
|
MaterialRef {ref {$material1}}
|
||||||
|
|
||||||
|
Transform
|
||||||
|
{
|
||||||
|
float[16]
|
||||||
|
{
|
||||||
|
{0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0
|
||||||
|
0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0
|
||||||
|
0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0
|
||||||
|
0x43041438, 0x411804DE, 0x00000000, 0x3F800000} // 132.079, 9.50119, 0, 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryObject $geometry1 // Box001, Box002
|
||||||
|
{
|
||||||
|
Mesh (primitive = "triangles")
|
||||||
|
{
|
||||||
|
VertexArray (attrib = "position")
|
||||||
|
{
|
||||||
|
float[3] // 24
|
||||||
|
{
|
||||||
|
{0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928},
|
||||||
|
{0xC2501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928},
|
||||||
|
{0x42501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexArray (attrib = "normal")
|
||||||
|
{
|
||||||
|
float[3] // 24
|
||||||
|
{
|
||||||
|
{0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000},
|
||||||
|
{0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x80000000, 0xBF800000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000},
|
||||||
|
{0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x80000000, 0x3F800000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexArray (attrib = "texcoord")
|
||||||
|
{
|
||||||
|
float[2] // 24
|
||||||
|
{
|
||||||
|
{0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
|
||||||
|
{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
|
||||||
|
{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexArray
|
||||||
|
{
|
||||||
|
unsigned_int32[3] // 12
|
||||||
|
{
|
||||||
|
{0, 1, 2}, {2, 3, 0}, {4, 5, 6}, {6, 7, 4}, {8, 9, 10}, {10, 11, 8}, {12, 13, 14}, {14, 15, 12}, {16, 17, 18}, {18, 19, 16}, {20, 21, 22}, {22, 23, 20}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Material $material1
|
||||||
|
{
|
||||||
|
Name {string {"03 - Default"}}
|
||||||
|
|
||||||
|
Color (attrib = "diffuse") {float[3] {{0.588235, 0.588235, 0.588235}}}
|
||||||
|
Texture (attrib = "diffuse")
|
||||||
|
{
|
||||||
|
string {"texture/Concrete.tga"}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,83 +3,81 @@ Assimp Regression Test Suite
|
||||||
|
|
||||||
1) How does it work?
|
1) How does it work?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
run.py checks all model in the <root>/test/models folder and compares the result
|
run.py checks all model in the <root>/test/models* folders and compares the result
|
||||||
against a regression database provided by us (db.zip). If the test passes
|
against a regression database provided with assimp (db.zip). A few failures
|
||||||
successfully, Assimp definitely WORKS perfectly on your system. A few failures
|
are totally fine (see sections 7+). You need to worry if a huge
|
||||||
are totally fine as well (see sections 7+). You need to worry if a huge
|
majority of all files in a particular format (or post-processing configuration)
|
||||||
majority of all files in a particular format or post-processing configuration
|
fails as this might be a sign of a recent regression in assimp's codebase or
|
||||||
fails - this might be a sign of a recent regression in assimp's codebase.
|
gross incompatibility with your system or compiler.
|
||||||
|
|
||||||
2) What do I need?
|
2) What do I need?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
- you need Python installed - 3.x !!
|
- You need Python installed (2.7+, 3.x). On Windows, run the scripts using "py".
|
||||||
- you need to build tools/assimp_cmd as described in the INSTALL file (
|
- You need to build the assimp command line tool (ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
make && make install on unixes,release-dll target with msvc).
|
CMake build flag). Both run.py and gen_db.py take the full path to the binary
|
||||||
|
as first command line parameter.
|
||||||
|
|
||||||
3) How to add more test files?
|
3) How to add more test files?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
Use the following procedure:
|
Use the following procedure:
|
||||||
- verify the correctness of your assimp build - run the regression suite.
|
- Verify the correctness of your assimp build - run the regression suite.
|
||||||
DO NOT continue if one or more tests fail.
|
DO NOT continue if more tests fail than usual.
|
||||||
- add your additional test files to <root>/test/models/<fileformat>, where
|
- Add your additional test files to <root>/test/models/<fileformat>, where
|
||||||
<fileformat> is the file type (typically the file extension)
|
<fileformat> is the file type (typically the file extension).
|
||||||
- rebuild the regression database using gen_db.py
|
- If you test file does not meet the BSD license requirements, add it to
|
||||||
- run the regression suite again - all tests should pass, including
|
<root>/test/models-nonbsd/<fileformat> so people know to be careful with it.
|
||||||
those for the new files.
|
- Rebuild the regression database:
|
||||||
|
"gen_db.py <binary> -ixyz" where .xyz is the file extension of the new file.
|
||||||
|
- Run the regression suite again. There should be no new failures and the new
|
||||||
|
file should not be among the failures.
|
||||||
|
- Include the db.zip file with your Pull Request. Travis CI enforces a passing
|
||||||
|
regression suite (with offenders whitelisted as a last resort).
|
||||||
|
|
||||||
- contributors: commit the db.zip plus your additional test files to
|
4) I made a change/fix/patch to a loader, how to update the database?
|
||||||
the SVN repository.
|
|
||||||
|
|
||||||
4) I made a change/fix/.. to a loader, how to update the database?
|
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
- rebuild the regression database using gen_db.py
|
- Rebuild the regression database using "gen_db.py <binary> -ixyz"
|
||||||
- run the suite - all tests should pass now. If they do not, don't continue
|
where .xyz is the file extension for which the loader was patched.
|
||||||
|
- Run the regression suite again. There should be no new failures and the new
|
||||||
- contributors: commit the db.zip to the SVN repository
|
file should not be among the failures.
|
||||||
|
- Include the db.zip file with your Pull Request. Travis CI enforces a passing
|
||||||
|
regression suite (with offenders whitelisted as a last resort).
|
||||||
|
|
||||||
5) How to add my whole model repository to the suite?
|
5) How to add my whole model repository to the database?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
|
|
||||||
Edit the reg_settings.py file and add the path to your repository to
|
Edit the reg_settings.py file and add the path to your repository to
|
||||||
<<model_directories>>. Then, rebuild the suite.
|
<<model_directories>>. Then, rebuild the database.
|
||||||
|
|
||||||
6) So what is actually verified?
|
6) So what is actually tested?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
The regression database includes mini dumps of the aiScene data structure -
|
The regression database includes mini dumps of the aiScene data structure, i.e.
|
||||||
the scene hierarchy plus the sizes of all data arrays MUST match. Floating-point
|
the scene hierarchy plus the sizes of all data arrays MUST match. Floating-point
|
||||||
data buffers, such as vertex positions, are handled less strictly: min,max and
|
data buffers, such as vertex positions are handled less strictly: min, max and
|
||||||
average values are stored with lower precision. This takes hardware- or
|
average values are stored with low precision. This takes hardware- or
|
||||||
compiler-specific differences in floating-point computations into account.
|
compiler-specific differences in floating-point computations into account.
|
||||||
Generally, almost all significant regressions will be detected while the
|
Generally, almost all significant regressions will be detected while the
|
||||||
number of false positives is relatively low.
|
number of false positives is relatively low.
|
||||||
|
|
||||||
7) The test suite fails, what do do?
|
7) The test suite fails, what do do?
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
Get back to ../results and check out regression_suite_failures.txt
|
Get back to <root>/test/results and look at regression_suite_failures.txt.
|
||||||
It contains a list of all files which failed the test ... they're copied to
|
It contains a list of all files which failed the test. Failing dumps are copied to
|
||||||
../results/tmp. Both an EXPECTED and an ACTUAL file is produced per test.
|
root>/test/results/tmp. Both an EXPECTED and an ACTUAL file is produced per test.
|
||||||
The output of `assimp cmpdump` is written to regressions_suite_output.txt.
|
The output of "assimp cmpdump" is written to regressions_suite_output.txt. Grep
|
||||||
To quickly find all all reports pertaining to tests which failed, I'd
|
for the file name in question and locate the log for the failed comparison. It
|
||||||
recommend grepping for 'but' because its a constituent of all error messages
|
contains a full trace of which scene elements have been compared before, which
|
||||||
produced by assimp_cmd :) Error reports contain detailed information
|
makes it reasonably easy to locate the offending field.
|
||||||
regarding the point of failure inside the data structure, the values of
|
|
||||||
the two corresponding fields that were found to be different from EXPECTED
|
|
||||||
and ACTUAL, respectively, ... this should offer you enough information to start
|
|
||||||
debugging.
|
|
||||||
|
|
||||||
8) fp:fast vs fp:precise fails the test suite (same for gcc equivalents)
|
8) fp:fast vs fp:precise fails the test suite (same for gcc equivalents)
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
As mentioned above, floating-point inaccuracies between differently optimized
|
As mentioned above, floating-point inaccuracies between differently optimized
|
||||||
builds are not considered regressions and all float comparisons done by the test
|
builds are not considered regressions and all float comparisons done by the test
|
||||||
suite involve an epsilon. Changing floating-point optimizations can, however,
|
suite involve an epsilon to accomodate. However compiler settings that allow
|
||||||
lead to *real* changes in the output data structure, such as different number
|
compilers to perform non-IEEE754 compliant optimizations can cause arbitrary
|
||||||
of vertices or faces, ... this violates one of our primary targets, that is
|
failures in the test suite. Even if the compiler is configured to be IEE754
|
||||||
produce reliable and portable output. We're working hard on removing these
|
comformant, there is lots of code in assimp that leaves the compiler a choice
|
||||||
issues, but at the moment you have to live with few of them.
|
and different compilers make different choices (for example the precision of
|
||||||
|
float intermediaries is implementation-specified).
|
||||||
Currently, the regression database is build on Windows using MSVC8 with
|
|
||||||
fp:precise. This leads to a small number of failures with fp:fast and
|
|
||||||
virtally every build with gcc. Be patient, it will be fixed.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -69,6 +69,9 @@ configs for an IDE, make sure to build the assimp_cmd project.
|
||||||
|
|
||||||
-i,--include: List of file extensions to update dumps for. If omitted,
|
-i,--include: List of file extensions to update dumps for. If omitted,
|
||||||
all file extensions are updated except those in `exclude`.
|
all file extensions are updated except those in `exclude`.
|
||||||
|
Example: -ixyz,abc
|
||||||
|
-i.xyz,.abc
|
||||||
|
--include=xyz,abc
|
||||||
|
|
||||||
-e,--exclude: Merged with settings.exclude_extensions to produce a
|
-e,--exclude: Merged with settings.exclude_extensions to produce a
|
||||||
list of all file extensions to ignore. If dumps exist,
|
list of all file extensions to ignore. If dumps exist,
|
||||||
|
@ -78,8 +81,6 @@ configs for an IDE, make sure to build the assimp_cmd project.
|
||||||
Dont' change anything.
|
Dont' change anything.
|
||||||
|
|
||||||
-n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files.
|
-n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files.
|
||||||
|
|
||||||
(lists of file extensions are comma delimited, i.e. `3ds,lwo,x`)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
@ -164,7 +165,7 @@ def gen_db(ext_list,outfile):
|
||||||
num = 0
|
num = 0
|
||||||
for tp in settings.model_directories:
|
for tp in settings.model_directories:
|
||||||
num += process_dir(tp, outfile,
|
num += process_dir(tp, outfile,
|
||||||
lambda x: os.path.splitext(x)[1] in ext_list)
|
lambda x: os.path.splitext(x)[1].lower() in ext_list and not x in settings.files_to_ignore)
|
||||||
|
|
||||||
print("="*60)
|
print("="*60)
|
||||||
print("Updated {0} entries".format(num))
|
print("Updated {0} entries".format(num))
|
||||||
|
@ -172,43 +173,44 @@ def gen_db(ext_list,outfile):
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
assimp_bin_path = sys.argv[1] if len(sys.argv) > 1 else 'assimp'
|
|
||||||
|
|
||||||
def clean(f):
|
def clean(f):
|
||||||
f = f.strip("* \'")
|
f = f.strip("* \'")
|
||||||
return "."+f if f[:1] != '.' else f
|
return "."+f if f[:1] != '.' else f
|
||||||
|
|
||||||
if len(sys.argv)>1 and (sys.argv[1] == "--help" or sys.argv[1] == "-h"):
|
if len(sys.argv) <= 1 or sys.argv[1] == "--help" or sys.argv[1] == "-h":
|
||||||
print(usage)
|
print(usage)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
assimp_bin_path = sys.argv[1]
|
||||||
ext_list, preview, nozip = None, False, False
|
ext_list, preview, nozip = None, False, False
|
||||||
for m in sys.argv[1:]:
|
for m in sys.argv[2:]:
|
||||||
if m[:10]=="--exclude=":
|
if m[:10]=="--exclude=":
|
||||||
settings.exclude_extensions += map(clean, m[10:].split(","))
|
settings.exclude_extensions += map(clean, m[10:].split(","))
|
||||||
elif m[:3]=="-e=":
|
elif m[:2]=="-e":
|
||||||
settings.exclude_extensions += map(clean, m[3:].split(","))
|
settings.exclude_extensions += map(clean, m[2:].split(","))
|
||||||
elif m[:10]=="--include=":
|
elif m[:10]=="--include=":
|
||||||
ext_list = m[10:].split(",")
|
ext_list = m[10:].split(",")
|
||||||
elif m[:3]=="-i=":
|
elif m[:2]=="-i":
|
||||||
ext_list = m[3:].split(",")
|
ext_list = m[2:].split(",")
|
||||||
elif m=="-p" or m == "--preview":
|
elif m=="-p" or m == "--preview":
|
||||||
preview = True
|
preview = True
|
||||||
elif m=="-n" or m == "--nozip":
|
elif m=="-n" or m == "--nozip":
|
||||||
nozip = True
|
nozip = True
|
||||||
|
else:
|
||||||
|
print("Unrecognized parameter: " + m)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
|
outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
|
||||||
if ext_list is None:
|
if ext_list is None:
|
||||||
(ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"],
|
(ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"],
|
||||||
stdout=subprocess.PIPE).communicate()
|
stdout=subprocess.PIPE).communicate()
|
||||||
ext_list = str(ext_list).lower().split(";")
|
ext_list = str(ext_list.strip()).lower().split(";")
|
||||||
|
|
||||||
# todo: Fix for multi dot extensions like .skeleton.xml
|
# todo: Fix for multi dot extensions like .skeleton.xml
|
||||||
ext_list = list(filter(lambda f: not f in settings.exclude_extensions,
|
ext_list = list(filter(lambda f: not f in settings.exclude_extensions,
|
||||||
map(clean, ext_list)))
|
map(clean, ext_list)))
|
||||||
|
print('File extensions processed: ' + ', '.join(ext_list))
|
||||||
if preview:
|
if preview:
|
||||||
print(','.join(ext_list))
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
extract_zip()
|
extract_zip()
|
||||||
|
|
|
@ -65,7 +65,7 @@ import utils
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
EXPECTED_FAILURE_NOT_MET, DATABASE_LENGTH_MISMATCH, \
|
EXPECTED_FAILURE_NOT_MET, DATABASE_LENGTH_MISMATCH, \
|
||||||
DATABASE_VALUE_MISMATCH, IMPORT_FAILURE, \
|
DATABASE_VALUE_MISMATCH, IMPORT_FAILURE, \
|
||||||
FILE_NOT_READABLE, COMPARE_SUCCESS = range(6)
|
FILE_NOT_READABLE, COMPARE_SUCCESS, EXPECTED_FAILURE = range(7)
|
||||||
|
|
||||||
messages = collections.defaultdict(lambda: "<unknown", {
|
messages = collections.defaultdict(lambda: "<unknown", {
|
||||||
EXPECTED_FAILURE_NOT_MET:
|
EXPECTED_FAILURE_NOT_MET:
|
||||||
|
@ -88,7 +88,10 @@ messages = collections.defaultdict(lambda: "<unknown", {
|
||||||
|
|
||||||
COMPARE_SUCCESS:
|
COMPARE_SUCCESS:
|
||||||
"""Results match archived reference dump in database\n\
|
"""Results match archived reference dump in database\n\
|
||||||
\tNumber of bytes compared: {0}"""
|
\tNumber of bytes compared: {0}""",
|
||||||
|
|
||||||
|
EXPECTED_FAILURE:
|
||||||
|
"""Expected failure was met.""",
|
||||||
})
|
})
|
||||||
|
|
||||||
outfilename_output = "run_regression_suite_output.txt"
|
outfilename_output = "run_regression_suite_output.txt"
|
||||||
|
@ -167,11 +170,11 @@ def process_dir(d, outfile_results, zipin, result):
|
||||||
print("Processing directory " + d)
|
print("Processing directory " + d)
|
||||||
for f in sorted(os.listdir(d)):
|
for f in sorted(os.listdir(d)):
|
||||||
fullpath = os.path.join(d, f)
|
fullpath = os.path.join(d, f)
|
||||||
if os.path.isdir(fullpath) and not f == ".svn":
|
if os.path.isdir(fullpath) and not f[:1] == '.':
|
||||||
process_dir(fullpath, outfile_results, zipin, result)
|
process_dir(fullpath, outfile_results, zipin, result)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if f in settings.files_to_ignore:
|
if f in settings.files_to_ignore or os.path.splitext(f)[1] in settings.exclude_extensions:
|
||||||
print("Ignoring " + f)
|
print("Ignoring " + f)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -190,32 +193,30 @@ def process_dir(d, outfile_results, zipin, result):
|
||||||
"regression database? Use gen_db.zip to re-generate.")
|
"regression database? Use gen_db.zip to re-generate.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Ignore extensions via settings.py configured list
|
|
||||||
# todo: Fix for multi dot extensions like .skeleton.xml
|
|
||||||
ext = os.path.splitext(fullpath)[1].lower()
|
|
||||||
if ext != "" and ext in settings.exclude_extensions:
|
|
||||||
continue
|
|
||||||
|
|
||||||
print("-"*60 + "\n " + os.path.realpath(fullpath) + " pp: " + pppreset)
|
print("-"*60 + "\n " + os.path.realpath(fullpath) + " pp: " + pppreset)
|
||||||
|
|
||||||
outfile_actual = prepare_output_dir(fullpath, filehash, "ACTUAL")
|
outfile_actual = prepare_output_dir(fullpath, filehash, "ACTUAL")
|
||||||
outfile_expect = prepare_output_dir(fullpath, filehash, "EXPECT")
|
outfile_expect = prepare_output_dir(fullpath, filehash, "EXPECT")
|
||||||
outfile_results.write("assimp dump "+"-"*80+"\n")
|
outfile_results.write("assimp dump "+"-"*80+"\n")
|
||||||
outfile_results.flush()
|
outfile_results.flush()
|
||||||
|
|
||||||
command = [assimp_bin_path,
|
command = [assimp_bin_path,
|
||||||
"dump",
|
"dump",
|
||||||
fullpath, outfile_actual, "-b", "-s", "-l" ] +\
|
fullpath, outfile_actual, "-b", "-s", "-l" ] +\
|
||||||
pppreset.split()
|
pppreset.split()
|
||||||
|
|
||||||
r = subprocess.call(command, **shellparams)
|
r = subprocess.call(command, **shellparams)
|
||||||
print(r)
|
outfile_results.flush()
|
||||||
|
|
||||||
if r and not failure:
|
if r and not failure:
|
||||||
result.fail(fullpath, outfile_expect, pppreset, IMPORT_FAILURE, r)
|
result.fail(fullpath, outfile_expect, pppreset, IMPORT_FAILURE, r)
|
||||||
|
outfile_results.write("Failed to import\n")
|
||||||
continue
|
continue
|
||||||
elif failure and not r:
|
elif failure and not r:
|
||||||
result.fail(fullpath, outfile_expect, pppreset, EXPECTED_FAILURE_NOT_MET)
|
result.fail(fullpath, outfile_expect, pppreset, EXPECTED_FAILURE_NOT_MET)
|
||||||
|
outfile_results.write("Expected import to fail\n")
|
||||||
|
continue
|
||||||
|
elif failure and r:
|
||||||
|
result.ok(fullpath, pppreset, EXPECTED_FAILURE)
|
||||||
|
outfile_results.write("Failed as expected, skipping.\n")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with open(outfile_expect, "wb") as s:
|
with open(outfile_expect, "wb") as s:
|
||||||
|
@ -227,21 +228,24 @@ def process_dir(d, outfile_results, zipin, result):
|
||||||
except IOError:
|
except IOError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
outfile_results.write("Expected data length: {0}\n".format(len(input_expected)))
|
||||||
|
outfile_results.write("Actual data length: {0}\n".format(len(input_actual)))
|
||||||
|
failed = False
|
||||||
if len(input_expected) != len(input_actual):
|
if len(input_expected) != len(input_actual):
|
||||||
result.fail(fullpath, outfile_expect, pppreset, DATABASE_LENGTH_MISMATCH,
|
result.fail(fullpath, outfile_expect, pppreset, DATABASE_LENGTH_MISMATCH,
|
||||||
len(input_expected), len(input_actual))
|
len(input_expected), len(input_actual))
|
||||||
continue
|
# Still compare the dumps to see what the difference is
|
||||||
|
failed = True
|
||||||
|
|
||||||
outfile_results.write("assimp cmpdump "+"-"*80+"\n")
|
outfile_results.write("assimp cmpdump "+"-"*80+"\n")
|
||||||
outfile_results.flush()
|
outfile_results.flush()
|
||||||
|
|
||||||
command = [ assimp_bin_path, 'cmpdump', outfile_actual, outfile_expect ]
|
command = [ assimp_bin_path, 'cmpdump', outfile_actual, outfile_expect ]
|
||||||
if subprocess.call(command, **shellparams) != 0:
|
if subprocess.call(command, **shellparams) != 0:
|
||||||
result.fail(fullpath, outfile_expect, pppreset, DATABASE_VALUE_MISMATCH)
|
if not failed:
|
||||||
|
result.fail(fullpath, outfile_expect, pppreset, DATABASE_VALUE_MISMATCH)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
result.ok(fullpath, pppreset, COMPARE_SUCCESS,
|
result.ok(fullpath, pppreset, COMPARE_SUCCESS, len(input_expected))
|
||||||
len(input_expected))
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
def del_folder_with_contents(folder):
|
def del_folder_with_contents(folder):
|
||||||
|
|
|
@ -60,9 +60,9 @@ files_to_ignore = ["pond.0.ply"]
|
||||||
# File extensions are case insensitive
|
# File extensions are case insensitive
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
exclude_extensions = [
|
exclude_extensions = [
|
||||||
".lws", ".assbin", ".assxml", ".txt", ".md",
|
".assbin", ".assxml", ".txt", ".md",
|
||||||
".jpeg", ".jpg", ".png", ".gif", ".tga", ".bmp",
|
".jpeg", ".jpg", ".png", ".gif", ".tga", ".bmp",
|
||||||
".skeleton", ".skeleton.xml"
|
".skeleton", ".skeleton.xml", ".license", ".mtl", ".material"
|
||||||
]
|
]
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,15 +50,13 @@ def hashing(file,pp):
|
||||||
needs to be persistent across different python implementations
|
needs to be persistent across different python implementations
|
||||||
and platforms, so we implement the hashing manually.
|
and platforms, so we implement the hashing manually.
|
||||||
"""
|
"""
|
||||||
|
file = file.lower()
|
||||||
file = file.replace('\\','/')+":"+pp
|
file = file.replace('\\','/')+":"+pp
|
||||||
# SDBM hash
|
# SDBM hash
|
||||||
res = 0
|
res = 0
|
||||||
for t in file:
|
for t in file:
|
||||||
res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
|
res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
|
||||||
|
return '{:x}'.format(res)
|
||||||
# Python 2.7 normalization: strip 'L' suffix.
|
|
||||||
return hex(res).rstrip('L')
|
|
||||||
|
|
||||||
|
|
||||||
# vim: ai ts=4 sts=4 et sw=4
|
# vim: ai ts=4 sts=4 et sw=4
|
||||||
|
|
|
@ -28,7 +28,7 @@ IF( WIN32 )
|
||||||
MAIN_DEPENDENCY assimp)
|
MAIN_DEPENDENCY assimp)
|
||||||
ENDIF( WIN32 )
|
ENDIF( WIN32 )
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES})
|
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} )
|
||||||
SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
|
SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
|
||||||
OUTPUT_NAME assimp
|
OUTPUT_NAME assimp
|
||||||
)
|
)
|
||||||
|
|
|
@ -140,15 +140,16 @@ public:
|
||||||
if(it != history.back().second.end()) {
|
if(it != history.back().second.end()) {
|
||||||
++history.back().second[s];
|
++history.back().second[s];
|
||||||
}
|
}
|
||||||
else history.back().second[s] = 1;
|
else history.back().second[s] = 0;
|
||||||
|
|
||||||
history.push_back(HistoryEntry(s,PerChunkCounter()));
|
history.push_back(HistoryEntry(s,PerChunkCounter()));
|
||||||
|
debug_trace.push_back("PUSH " + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* leave current scope */
|
/* leave current scope */
|
||||||
void pop_elem() {
|
void pop_elem() {
|
||||||
ai_assert(history.size());
|
ai_assert(history.size());
|
||||||
|
debug_trace.push_back("POP "+ history.back().first);
|
||||||
history.pop_back();
|
history.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,30 +250,50 @@ private:
|
||||||
const char* last = history.back().first.c_str();
|
const char* last = history.back().first.c_str();
|
||||||
std::string pad;
|
std::string pad;
|
||||||
|
|
||||||
for(ChunkHistory::reverse_iterator rev = ++history.rbegin(),
|
for(ChunkHistory::reverse_iterator rev = history.rbegin(),
|
||||||
end = history.rend(); rev < end; ++rev, pad += " ")
|
end = history.rend(); rev != end; ++rev, pad += " ")
|
||||||
{
|
{
|
||||||
ss << pad << (*rev).first << "(Index: " << (*rev).second[last]-1 << ")" << std::endl;
|
ss << pad << (*rev).first << "(Index: " << (*rev).second[last] << ")" << std::endl;
|
||||||
last = (*rev).first.c_str();
|
last = (*rev).first.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ss << std::endl << "Debug trace: "<< std::endl;
|
||||||
|
for (std::vector<std::string>::const_iterator it = debug_trace.begin(); it != debug_trace.end(); ++it) {
|
||||||
|
ss << *it << std::endl;
|
||||||
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* read from both streams simult.*/
|
/* read from both streams at the same time */
|
||||||
template <typename T> void read(T& filla,T& fille) {
|
template <typename T> void read(T& filla,T& fille) {
|
||||||
if(1 != fread(&filla,sizeof(T),1,actual)) {
|
if(1 != fread(&filla,sizeof(T),1,actual)) {
|
||||||
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
|
EOFActual();
|
||||||
}
|
}
|
||||||
if(1 != fread(&fille,sizeof(T),1,expect)) {
|
if(1 != fread(&fille,sizeof(T),1,expect)) {
|
||||||
throw compare_fails_exception("Unexpected EOF reading EXPECT");
|
EOFExpect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void EOFActual() {
|
||||||
|
std::stringstream ss;
|
||||||
|
throw compare_fails_exception((ss
|
||||||
|
<< "Unexpected EOF reading ACTUAL.\nCurrent position in scene hierarchy is "
|
||||||
|
<< print_hierarchy(),ss.str().c_str()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EOFExpect() {
|
||||||
|
std::stringstream ss;
|
||||||
|
throw compare_fails_exception((ss
|
||||||
|
<< "Unexpected EOF reading EXPECT.\nCurrent position in scene hierarchy is "
|
||||||
|
<< print_hierarchy(),ss.str().c_str()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FILE *const actual, *const expect;
|
FILE *const actual, *const expect;
|
||||||
|
|
||||||
typedef std::map<std::string,unsigned int> PerChunkCounter;
|
typedef std::map<std::string,unsigned int> PerChunkCounter;
|
||||||
|
@ -281,6 +302,8 @@ private:
|
||||||
typedef std::deque<HistoryEntry> ChunkHistory;
|
typedef std::deque<HistoryEntry> ChunkHistory;
|
||||||
ChunkHistory history;
|
ChunkHistory history;
|
||||||
|
|
||||||
|
std::vector<std::string> debug_trace;
|
||||||
|
|
||||||
typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack;
|
typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack;
|
||||||
LengthStack lengths;
|
LengthStack lengths;
|
||||||
|
|
||||||
|
@ -296,10 +319,10 @@ template <> void comparer_context :: read<aiString>(aiString& filla,aiString& fi
|
||||||
read(lena,lene);
|
read(lena,lene);
|
||||||
|
|
||||||
if(lena && 1 != fread(&filla.data,lena,1,actual)) {
|
if(lena && 1 != fread(&filla.data,lena,1,actual)) {
|
||||||
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
|
EOFActual();
|
||||||
}
|
}
|
||||||
if(lene && 1 != fread(&fille.data,lene,1,expect)) {
|
if(lene && 1 != fread(&fille.data,lene,1,expect)) {
|
||||||
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
|
EOFExpect();
|
||||||
}
|
}
|
||||||
|
|
||||||
fille.data[fille.length=static_cast<unsigned int>(lene)] = '\0';
|
fille.data[fille.length=static_cast<unsigned int>(lene)] = '\0';
|
||||||
|
@ -493,7 +516,7 @@ private:
|
||||||
res|=fread(&actual.second,4,1,ctx.get_actual()) <<3u;
|
res|=fread(&actual.second,4,1,ctx.get_actual()) <<3u;
|
||||||
|
|
||||||
if(res!=0xf) {
|
if(res!=0xf) {
|
||||||
ctx.failure("I/OError reading chunk head, dumps are not well-defined","<ChunkHead>");
|
ctx.failure("IO Error reading chunk head, dumps are malformed","<ChunkHead>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.first != actual.first) {
|
if (current.first != actual.first) {
|
||||||
|
@ -510,7 +533,7 @@ private:
|
||||||
if (current.first != actual.first) {
|
if (current.first != actual.first) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ctx.failure((ss
|
ctx.failure((ss
|
||||||
<<"Chunk lenghts do not match. EXPECT: "
|
<<"Chunk lengths do not match. EXPECT: "
|
||||||
<<current.second
|
<<current.second
|
||||||
<<" ACTUAL: "
|
<<" ACTUAL: "
|
||||||
<< actual.second,
|
<< actual.second,
|
||||||
|
@ -729,7 +752,7 @@ void CompareOnTheFlyLight(comparer_context& comp) {
|
||||||
const aiLightSourceType type = static_cast<aiLightSourceType>(
|
const aiLightSourceType type = static_cast<aiLightSourceType>(
|
||||||
comp.cmp<uint32_t>("mType"));
|
comp.cmp<uint32_t>("mType"));
|
||||||
|
|
||||||
if(type==aiLightSource_DIRECTIONAL) {
|
if(type!=aiLightSource_DIRECTIONAL) {
|
||||||
comp.cmp<float>("mAttenuationConstant");
|
comp.cmp<float>("mAttenuationConstant");
|
||||||
comp.cmp<float>("mAttenuationLinear");
|
comp.cmp<float>("mAttenuationLinear");
|
||||||
comp.cmp<float>("mAttenuationQuadratic");
|
comp.cmp<float>("mAttenuationQuadratic");
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
LOCAL_PATH := $(call my-dir)/../../../
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := assimp_static
|
||||||
|
ASSIMP_SRC_DIR = code
|
||||||
|
|
||||||
|
FILE_LIST := $(wildcard $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/*.cpp)
|
||||||
|
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/openddlparser/code/*.cpp)
|
||||||
|
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/unzip/*.c)
|
||||||
|
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/poly2tri/poly2tri/*/*.cc)
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += contrib/clipper/clipper.cpp \
|
||||||
|
contrib/ConvertUTF/ConvertUTF.c \
|
||||||
|
contrib/irrXML/irrXML.cpp
|
||||||
|
|
||||||
|
# enables -frtti and -fexceptions
|
||||||
|
LOCAL_CPP_FEATURES := exceptions
|
||||||
|
# identifier 'nullptr' will become a keyword in C++0x [-Wc++0x-compat]
|
||||||
|
# but next breaks blender and other importer
|
||||||
|
# LOCAL_CFLAGS += -std=c++11
|
||||||
|
|
||||||
|
# cant be disabled? rudamentary function?
|
||||||
|
# -DASSIMP_BUILD_NO_FLIPWINDING_PROCESS \
|
||||||
|
#
|
||||||
|
DontBuildProcess = \
|
||||||
|
-DASSIMP_BUILD_NO_FLIPUVS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_CALCTANGENTS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_DEBONE_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_FINDINSTANCES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_GENFACENORMALS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_GENUVCOORDS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_JOINVERTICES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_REMOVEVC_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_TRIANGULATE_PROCESS \
|
||||||
|
-DASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||||
|
|
||||||
|
DontBuildImporters = \
|
||||||
|
-DASSIMP_BUILD_NO_X_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_3DS_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MD3_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MDL_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MD2_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_PLY_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_ASE_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_HMP_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_SMD_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MDC_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MD5_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_STL_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_LWO_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_DXF_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_NFF_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_RAW_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_OFF_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_AC_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_BVH_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_IRRMESH_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_IRR_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_Q3D_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_B3D_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_COLLADA_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_TERRAGEN_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_CSM_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_3D_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_LWS_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_OGRE_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_MS3D_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_COB_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_Q3BSP_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_NDO_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_IFC_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_XGL_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_FBX_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_C4D_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_OPENGEX_IMPORTER \
|
||||||
|
-DASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
# -DASSIMP_BUILD_NO_BLEND_IMPORTER \
|
||||||
|
# -DASSIMP_BUILD_NO_GEO_IMPORTER
|
||||||
|
# -DASSIMP_BUILD_NO_OBJ_IMPORTER \
|
||||||
|
#
|
||||||
|
DontBuildImporters := -DASSIMP_BUILD_NO_IFC_IMPORTER -DASSIMP_BUILD_NO_IRRMESH_IMPORTER -DASSIMP_BUILD_NO_IRR_IMPORTER -DASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
|
|
||||||
|
ASSIMP_FLAGS_3_0 = -DASSIMP_BUILD_DLL_EXPORT -DASSIMP_BUILD_NO_OWN_ZLIB -DASSIMP_BUILD_BOOST_WORKAROUND -Dassimp_EXPORTS -fPIC -fvisibility=hidden -Wall
|
||||||
|
ASSIMP_FLAGS_3_1 = $(ASSIMP_FLAGS_3_0) # -DASSIMP_BUILD_BLENDER_DEBUG
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += $(ASSIMP_FLAGS_3_1) -DASSIMP_BUILD_NO_EXPORT -DOPENDDL_NO_USE_CPP11 $(DontBuildImporters) # $(DontBuildProcess)
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround $(LOCAL_PATH)/contrib/openddlparser/include ./
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := assimp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += -UASSIMP_BUILD_DLL_EXPORT
|
||||||
|
LOCAL_WHOLE_STATIC_LIBRARIES = assimp_static
|
||||||
|
|
||||||
|
LOCAL_LDLIBS := -lz
|
||||||
|
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
-include $(LOCAL_PATH)/assimp_cmd.mk
|
||||||
|
|
||||||
|
# let it on original place
|
||||||
|
include $(LOCAL_PATH)/port/jassimp/jassimp-native/Android.mk
|
|
@ -0,0 +1,8 @@
|
||||||
|
ifeq ($(CC),clang)
|
||||||
|
NDK_TOOLCHAIN_VERSION := $(CC)
|
||||||
|
$(info "Use llvm Compiler")
|
||||||
|
endif
|
||||||
|
|
||||||
|
APP_ABI := armeabi-v7a
|
||||||
|
|
||||||
|
APP_STL := stlport_static
|
Loading…
Reference in New Issue