Merge remote-tracking branch 'origin'
Conflicts: code/C4DImporter.cpp code/OgreImporter.hpull/536/head
commit
8c45a4dc3b
|
@ -10,7 +10,7 @@ build
|
|||
# Output
|
||||
bin/
|
||||
lib/
|
||||
contrib/
|
||||
|
||||
|
||||
# Generated
|
||||
assimp.pc
|
||||
|
@ -54,3 +54,7 @@ tools/assimp_view/assimp_viewer.vcxproj.user
|
|||
|
||||
# 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
|
||||
|
|
49
.travis.yml
49
.travis.yml
|
@ -1,16 +1,22 @@
|
|||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- 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:
|
||||
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=NO
|
||||
- LINUX=1 TRAVIS_STATIC_BUILD=ON
|
||||
- LINUX=1 TRAVIS_STATIC_BUILD=OFF
|
||||
- WINDOWS=1 TRAVIS_NO_EXPORT=YES
|
||||
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
|
||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=ON
|
||||
- WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
|
||||
- LINUX=1 SHARED_BUILD=ON
|
||||
- LINUX=1 SHARED_BUILD=OFF
|
||||
- ANDROID=1
|
||||
|
||||
language: cpp
|
||||
|
||||
|
@ -19,19 +25,22 @@ compiler:
|
|||
- clang
|
||||
|
||||
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:
|
||||
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
|
||||
- make
|
||||
- sudo make install
|
||||
- sudo ldconfig
|
||||
- cd test/unit
|
||||
- ../../bin/unit
|
||||
- cd ../regression
|
||||
- chmod 755 run.py
|
||||
- ./run.py
|
||||
- echo "=========================================================="
|
||||
- echo "REGRESSION TEST FAILS (results/run_regression_suite_failures.csv)"
|
||||
- cat ../results/run_regression_suite_failures.csv
|
||||
|
||||
- if [ $ANDROID ]; then
|
||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ;
|
||||
else
|
||||
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD ;
|
||||
make ;
|
||||
sudo make install ;
|
||||
sudo ldconfig ;
|
||||
cd test/unit ;
|
||||
../../bin/unit ;
|
||||
cd ../regression ;
|
||||
chmod 755 run.py ;
|
||||
./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 )
|
||||
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
|
||||
set (ASSIMP_VERSION_MAJOR 3)
|
||||
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")
|
||||
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
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")
|
||||
|
||||
# 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
|
||||
IF (NOT TARGET uninstall)
|
||||
# add make uninstall capability
|
||||
|
|
5
CREDITS
5
CREDITS
|
@ -151,3 +151,8 @@ Ogre Binary format support
|
|||
|
||||
- Filip Wasil, Tieto Poland Sp. z o.o.
|
||||
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 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 ####
|
||||
|
||||
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
|
||||
- BLEND (Blender 3D)
|
||||
- BLEND (Blender)
|
||||
- DAE/Collada
|
||||
- FBX
|
||||
- IFC-STEP
|
||||
|
@ -46,13 +53,13 @@ The library provides importers for a lot of file formats, including:
|
|||
- Ogre Binary
|
||||
- Ogre XML
|
||||
- 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)
|
||||
|
||||
Exporters include:
|
||||
__Exporters__:
|
||||
|
||||
- DAE (Collada)
|
||||
- STL
|
||||
|
@ -63,23 +70,21 @@ Exporters include:
|
|||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||
- 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 ####
|
||||
|
||||
|
||||
Open Asset Import Library is implemented in C++ (but provides both a C and a
|
||||
C++ish interface). The directory structure is:
|
||||
Open Asset Import Library is implemented in C++. The directory structure is:
|
||||
|
||||
/bin Folder for binaries, only used on Windows
|
||||
/code Source code
|
||||
/contrib Third-party libraries
|
||||
/doc Documentation (doxysource and pre-compiled docs)
|
||||
/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
|
||||
/port Ports to other languages and scripts to maintain those.
|
||||
/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!)
|
||||
|
||||
|
||||
|
||||
### 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 ###
|
||||
|
||||
|
||||
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).
|
||||
|
||||
If the documentation doesn't solve your problems,
|
||||
[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).
|
||||
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.
|
||||
|
||||
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)
|
||||
|
||||
### 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
|
||||
a pull request with your changes against the main repository's `master` branch.
|
||||
|
||||
|
||||
### 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 -
|
||||
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
|
||||
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"));
|
||||
if(!outfile) {
|
||||
|
@ -191,8 +191,8 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
|
|||
|
||||
{
|
||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
||||
WriteMeshes();
|
||||
WriteMaterials();
|
||||
WriteMeshes();
|
||||
|
||||
{
|
||||
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;
|
||||
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
||||
|
|
|
@ -623,7 +623,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
|||
|
||||
} // 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" );
|
||||
if (!out) return;
|
||||
|
|
|
@ -123,6 +123,16 @@ namespace Blender {
|
|||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4351)
|
||||
#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
|
||||
* the various ConvertXXX routines in BlenderImporter.*/
|
||||
|
@ -135,7 +145,13 @@ namespace Blender {
|
|||
, 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, aiCamera> cameras;
|
||||
|
|
|
@ -561,24 +561,26 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
|||
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
||||
|
||||
if (index == static_cast<unsigned int>( -1 )) {
|
||||
|
||||
// ok, we need to add a dedicated default material for some poor material-less meshes
|
||||
// Setup a default 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 );
|
||||
|
||||
// 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->specr = p->specg = p->specb = 0.6f;
|
||||
p->ambr = p->ambg = p->ambb = 0.0f;
|
||||
p->mirr = p->mirg = p->mirb = 0.0f;
|
||||
p->emit = 0.f;
|
||||
p->alpha = 0.f;
|
||||
|
||||
// XXX add more / or add default c'tor to Material
|
||||
p->har = 0;
|
||||
|
||||
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
||||
conv_data.materials_raw.push_back(p);
|
||||
|
||||
LogInfo("Adding default material ...");
|
||||
LogInfo("Adding default material");
|
||||
}
|
||||
mesh->mMaterialIndex = index;
|
||||
}
|
||||
|
@ -593,6 +595,7 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
|||
|
||||
aiMaterial* mout = new aiMaterial();
|
||||
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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (object->parent == obj) {
|
||||
children.push_back(object);
|
||||
|
|
|
@ -129,9 +129,11 @@ public:
|
|||
{
|
||||
case aiOrigin_CUR:
|
||||
cursor += pOffset;
|
||||
break;
|
||||
|
||||
case aiOrigin_END:
|
||||
cursor = file_size - pOffset;
|
||||
break;
|
||||
|
||||
case aiOrigin_SET:
|
||||
cursor = pOffset;
|
||||
|
|
|
@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
/** @file C4DImporter.cpp
|
||||
* @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
|
||||
// where it is turned on in the CMake settings.
|
||||
|
|
|
@ -266,8 +266,6 @@ SET( LWS_SRCS
|
|||
)
|
||||
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
||||
|
||||
|
||||
|
||||
SET( MD2_SRCS
|
||||
MD2FileData.h
|
||||
MD2Loader.cpp
|
||||
|
@ -361,6 +359,13 @@ SET( 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
|
||||
PlyLoader.cpp
|
||||
PlyLoader.h
|
||||
|
@ -636,6 +641,17 @@ SET( 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
|
||||
if(MSVC10)
|
||||
|
@ -691,6 +707,7 @@ SET( assimp_src
|
|||
${OFFFormat_SRCS}
|
||||
${Obj_SRCS}
|
||||
${Ogre_SRCS}
|
||||
${OpenGEX_SRCS}
|
||||
${Ply_SRCS}
|
||||
${Q3D_SRCS}
|
||||
${Q3BSP_SRCS}
|
||||
|
@ -715,6 +732,7 @@ SET( assimp_src
|
|||
${unzip_compile_SRCS}
|
||||
${Poly2Tri_SRCS}
|
||||
${Clipper_SRCS}
|
||||
${openddl_parser_SRCS}
|
||||
# Necessary to show the headers in the project when using the VC++ generator:
|
||||
${Boost_SRCS}
|
||||
|
||||
|
@ -722,6 +740,11 @@ SET( assimp_src
|
|||
${COMPILER_HEADERS}
|
||||
|
||||
)
|
||||
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../contrib/openddlparser/include
|
||||
)
|
||||
|
||||
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||
SET( assimp_src ${assimp_src} ${C4D_SRCS})
|
||||
|
@ -730,7 +753,7 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
|||
|
||||
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)
|
||||
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));
|
||||
void (COBImporter::* load)(Scene&,StreamReaderLE*)= head[15]=='A'?&COBImporter::ReadAsciiFile:&COBImporter::ReadBinaryFile;
|
||||
if (head[16]!='L') {
|
||||
ThrowException("File is big-endian, which is not supported");
|
||||
}
|
||||
|
||||
// load data into intermediate structures
|
||||
(this->*load)(scene,stream.get());
|
||||
if (head[15]=='A') {
|
||||
ReadAsciiFile(scene, stream.get());
|
||||
}
|
||||
else {
|
||||
ReadBinaryFile(scene, stream.get());
|
||||
}
|
||||
if(scene.nodes.empty()) {
|
||||
ThrowException("No nodes loaded");
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace Assimp
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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 file = pFile;
|
||||
|
|
|
@ -405,6 +405,7 @@ struct Controller
|
|||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
||||
struct Material
|
||||
{
|
||||
std::string mName;
|
||||
std::string mEffect;
|
||||
};
|
||||
|
||||
|
|
|
@ -1385,7 +1385,7 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
|
|||
|
||||
// create material
|
||||
aiMaterial* mat = new aiMaterial;
|
||||
aiString name( matIt->first);
|
||||
aiString name( material.mName.empty() ? matIt->first : material.mName );
|
||||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||
|
||||
// store the material
|
||||
|
|
|
@ -66,7 +66,7 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
|
|||
{
|
||||
mRootNode = NULL;
|
||||
mUnitSize = 1.0f;
|
||||
mUpDirection = UP_Z;
|
||||
mUpDirection = UP_Y;
|
||||
|
||||
// We assume the newest file format by default
|
||||
mFormat = FV_1_5_n;
|
||||
|
@ -231,10 +231,10 @@ void ColladaParser::ReadAssetInfo()
|
|||
const char* content = GetTextContent();
|
||||
if( strncmp( content, "X_UP", 4) == 0)
|
||||
mUpDirection = UP_X;
|
||||
else if( strncmp( content, "Y_UP", 4) == 0)
|
||||
mUpDirection = UP_Y;
|
||||
else
|
||||
else if( strncmp( content, "Z_UP", 4) == 0)
|
||||
mUpDirection = UP_Z;
|
||||
else
|
||||
mUpDirection = UP_Y;
|
||||
|
||||
// check element end
|
||||
TestClosing( "up_axis");
|
||||
|
@ -823,6 +823,7 @@ void ColladaParser::ReadMaterialLibrary()
|
|||
if( mReader->isEmptyElement())
|
||||
return;
|
||||
|
||||
std::map<std::string, int> names;
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
|
@ -833,8 +834,32 @@ void ColladaParser::ReadMaterialLibrary()
|
|||
int attrID = GetAttribute( "id");
|
||||
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
|
||||
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
|
||||
{
|
||||
// ignore the rest
|
||||
|
@ -1391,6 +1416,9 @@ void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
|
|||
if( attrTex >= 0 )
|
||||
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
|
||||
//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"))
|
||||
{
|
||||
|
@ -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
|
||||
actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
|
||||
}
|
||||
}
|
||||
else if (IsElement("extra"))
|
||||
{
|
||||
SkipElement("extra");
|
||||
} else
|
||||
{
|
||||
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
|
||||
if (primType != Prim_TriFans && primType != Prim_TriStrips)
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
if (primType != Prim_TriFans && primType != Prim_TriStrips) {
|
||||
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
|
||||
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
|
||||
// do not use const, because some exporter need to convert the scene temporary
|
||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
||||
void ExportSceneXFile(const char*,IOSystem*, const aiScene*);
|
||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
||||
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
||||
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*);
|
||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
|
||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
|
||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
|
||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER
|
||||
#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
|
||||
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
||||
#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) {
|
||||
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();
|
||||
|
||||
|
@ -403,7 +403,8 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
|||
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) {
|
||||
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
|
||||
|
|
|
@ -1971,9 +1971,12 @@ private:
|
|||
|
||||
// strip AnimationStack:: prefix
|
||||
std::string name = st.Name();
|
||||
if(name.substr(0,16) == "AnimationStack::") {
|
||||
if (name.substr(0, 16) == "AnimationStack::") {
|
||||
name = name.substr(16);
|
||||
}
|
||||
else if (name.substr(0, 11) == "AnimStack::") {
|
||||
name = name.substr(11);
|
||||
}
|
||||
|
||||
anim->mName.Set(name);
|
||||
|
||||
|
@ -2017,12 +2020,18 @@ private:
|
|||
double min_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 {
|
||||
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
|
||||
GenerateNodeAnimations(node_anims,
|
||||
kv.first,
|
||||
kv.second,
|
||||
layer_map,
|
||||
start_time, stop_time,
|
||||
max_time,
|
||||
min_time);
|
||||
}
|
||||
|
@ -2046,9 +2055,27 @@ private:
|
|||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -2058,6 +2085,7 @@ private:
|
|||
const std::string& fixed_name,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
int64_t start, int64_t stop,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
|
@ -2150,13 +2178,19 @@ private:
|
|||
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||
node_property_map.end(),
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time,
|
||||
true // input is TRS order, assimp is SRT
|
||||
);
|
||||
|
||||
ai_assert(nd);
|
||||
if (nd->mNumPositionKeys == 0 && nd->mNumRotationKeys == 0 && nd->mNumScalingKeys == 0) {
|
||||
delete nd;
|
||||
}
|
||||
else {
|
||||
node_anims.push_back(nd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2188,6 +2222,7 @@ private:
|
|||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time);
|
||||
|
||||
|
@ -2203,6 +2238,7 @@ private:
|
|||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time);
|
||||
|
||||
|
@ -2215,12 +2251,18 @@ private:
|
|||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time,
|
||||
true);
|
||||
|
||||
ai_assert(inv);
|
||||
if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
|
||||
delete inv;
|
||||
}
|
||||
else {
|
||||
node_anims.push_back(inv);
|
||||
}
|
||||
|
||||
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||
|
@ -2233,12 +2275,18 @@ private:
|
|||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time,
|
||||
true);
|
||||
|
||||
ai_assert(inv);
|
||||
if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
|
||||
delete inv;
|
||||
}
|
||||
else {
|
||||
node_anims.push_back(inv);
|
||||
}
|
||||
|
||||
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||
|
@ -2252,6 +2300,7 @@ private:
|
|||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time);
|
||||
|
||||
|
@ -2262,7 +2311,12 @@ private:
|
|||
}
|
||||
|
||||
ai_assert(na);
|
||||
if (na->mNumPositionKeys == 0 && na->mNumRotationKeys == 0 && na->mNumScalingKeys == 0) {
|
||||
delete na;
|
||||
}
|
||||
else {
|
||||
node_anims.push_back(na);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2323,13 +2377,14 @@ private:
|
|||
const Model& target,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
int64_t start, int64_t stop,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
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
|
||||
na->mScalingKeys = new aiVectorKey[1];
|
||||
|
@ -2354,13 +2409,14 @@ private:
|
|||
const Model& /*target*/,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
int64_t start, int64_t stop,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
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
|
||||
na->mRotationKeys = new aiQuatKey[1];
|
||||
|
@ -2385,6 +2441,7 @@ private:
|
|||
const Model& /*target*/,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
int64_t start, int64_t stop,
|
||||
double& max_time,
|
||||
double& min_time,
|
||||
bool inverse = false)
|
||||
|
@ -2392,7 +2449,7 @@ private:
|
|||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
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) {
|
||||
for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) {
|
||||
|
@ -2425,6 +2482,7 @@ private:
|
|||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||
NodeMap::const_iterator iter_end,
|
||||
const LayerMap& layer_map,
|
||||
int64_t start, int64_t stop,
|
||||
double& max_time,
|
||||
double& min_time,
|
||||
bool reverse_order = false)
|
||||
|
@ -2446,21 +2504,21 @@ private:
|
|||
KeyFrameListList rotation;
|
||||
|
||||
if(chain[TransformationComp_Scaling] != iter_end) {
|
||||
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second);
|
||||
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
|
||||
}
|
||||
else {
|
||||
def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
|
||||
}
|
||||
|
||||
if(chain[TransformationComp_Translation] != iter_end) {
|
||||
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second);
|
||||
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
|
||||
}
|
||||
else {
|
||||
def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
|
||||
}
|
||||
|
||||
if(chain[TransformationComp_Rotation] != iter_end) {
|
||||
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second);
|
||||
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
|
||||
}
|
||||
else {
|
||||
def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
|
||||
|
@ -2478,6 +2536,8 @@ private:
|
|||
aiVectorKey* out_scale = new aiVectorKey[times.size()];
|
||||
aiVectorKey* out_translation = new aiVectorKey[times.size()];
|
||||
|
||||
if (times.size())
|
||||
{
|
||||
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
|
||||
scaling,
|
||||
translation,
|
||||
|
@ -2489,6 +2549,7 @@ private:
|
|||
def_scale,
|
||||
def_translate,
|
||||
def_rot);
|
||||
}
|
||||
|
||||
// XXX remove duplicates / redundant keys which this operation did
|
||||
// likely produce if not all three channels were equally dense.
|
||||
|
@ -2510,6 +2571,7 @@ private:
|
|||
if(chain[TransformationComp_Scaling] != iter_end) {
|
||||
ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time);
|
||||
}
|
||||
|
@ -2525,6 +2587,7 @@ private:
|
|||
if(chain[TransformationComp_Rotation] != iter_end) {
|
||||
ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time,
|
||||
target.RotationOrder());
|
||||
|
@ -2542,6 +2605,7 @@ private:
|
|||
if(chain[TransformationComp_Translation] != iter_end) {
|
||||
ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
min_time);
|
||||
}
|
||||
|
@ -2561,17 +2625,21 @@ private:
|
|||
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes)
|
||||
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop)
|
||||
{
|
||||
KeyFrameListList inputs;
|
||||
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) {
|
||||
ai_assert(node);
|
||||
|
||||
|
@ -2596,7 +2664,23 @@ private:
|
|||
const AnimationCurve* const curve = kv.second;
|
||||
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 :-)
|
||||
|
@ -2626,7 +2710,7 @@ private:
|
|||
const size_t count = inputs.size();
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
keys.push_back(min_tick);
|
||||
|
@ -2835,6 +2919,7 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
double& maxTime,
|
||||
double& minTime)
|
||||
{
|
||||
|
@ -2844,11 +2929,12 @@ private:
|
|||
// layers should be multiplied with each other). There is a FBX
|
||||
// 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);
|
||||
|
||||
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
||||
na->mScalingKeys = new aiVectorKey[keys.size()];
|
||||
if (keys.size() > 0)
|
||||
InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
|
||||
}
|
||||
|
||||
|
@ -2856,17 +2942,19 @@ private:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
double& maxTime,
|
||||
double& minTime)
|
||||
{
|
||||
ai_assert(nodes.size());
|
||||
|
||||
// XXX see notes in ConvertScaleKeys()
|
||||
const KeyFrameListList& inputs = GetKeyframeList(nodes);
|
||||
const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop);
|
||||
const KeyTimeList& keys = GetKeyTimeList(inputs);
|
||||
|
||||
na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
|
||||
na->mPositionKeys = new aiVectorKey[keys.size()];
|
||||
if (keys.size() > 0)
|
||||
InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
|
||||
}
|
||||
|
||||
|
@ -2874,6 +2962,7 @@ private:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
double& maxTime,
|
||||
double& minTime,
|
||||
Model::RotOrder order)
|
||||
|
@ -2881,11 +2970,12 @@ private:
|
|||
ai_assert(nodes.size());
|
||||
|
||||
// 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);
|
||||
|
||||
na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
|
||||
na->mRotationKeys = new aiQuatKey[keys.size()];
|
||||
if (keys.size() > 0)
|
||||
InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
|
||||
}
|
||||
|
||||
|
|
|
@ -882,7 +882,7 @@ private:
|
|||
std::vector<unsigned int> mappings;
|
||||
};
|
||||
|
||||
typedef std::vector<uint64_t> KeyTimeList;
|
||||
typedef std::vector<int64_t> KeyTimeList;
|
||||
typedef std::vector<float> KeyValueList;
|
||||
|
||||
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
|
||||
|
@ -1026,10 +1026,10 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
fbx_simple_property(LocalStart, uint64_t, 0L)
|
||||
fbx_simple_property(LocalStop, uint64_t, 0L)
|
||||
fbx_simple_property(ReferenceStart, uint64_t, 0L)
|
||||
fbx_simple_property(ReferenceStop, uint64_t, 0L)
|
||||
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||
fbx_simple_property(ReferenceStart, int64_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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
} // !Assimp
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ size_t ParseTokenAsDim(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);
|
||||
int64_t ParseTokenAsInt64(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);
|
||||
float ParseTokenAsFloat(const Token& t);
|
||||
int ParseTokenAsInt(const Token& t);
|
||||
int64_t ParseTokenAsInt64(const Token& t);
|
||||
std::string ParseTokenAsString(const Token& t);
|
||||
|
||||
/* 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<unsigned int>& out, const Element& el);
|
||||
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")) {
|
||||
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]));
|
||||
}
|
||||
else if (!strcmp(cs, "KTime")) {
|
||||
return new TypedProperty<int64_t>(ParseTokenAsInt64(*tok[4]));
|
||||
}
|
||||
else if (!strcmp(cs,"Vector3D") ||
|
||||
!strcmp(cs,"ColorRGB") ||
|
||||
!strcmp(cs,"Vector") ||
|
||||
|
@ -105,7 +108,7 @@ Property* ReadTypedProperty(const Element& element)
|
|||
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 NULL;
|
||||
|
|
|
@ -111,5 +111,18 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
|||
*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
|
||||
|
|
|
@ -648,10 +648,10 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
|||
ai_assert(InRange(a) && InRange(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;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -523,43 +523,23 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
|||
return m;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
|
||||
ConversionData& conv, bool collect_openings)
|
||||
// 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,
|
||||
const IfcVector3& extrusionDir, 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; /*
|
||||
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;
|
||||
// Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
|
||||
// forming new triangles.
|
||||
const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.verts.size() > 2;
|
||||
if( solid.Depth < 1e-6 ) {
|
||||
if( has_area ) {
|
||||
result.Append(curve);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
result.verts.reserve(size*(has_area?4:2));
|
||||
result.vertcnt.reserve(meshout.vertcnt.size()+2);
|
||||
result.verts.reserve(curve.verts.size()*(has_area ? 4 : 2));
|
||||
result.vertcnt.reserve(curve.verts.size() + 2);
|
||||
std::vector<IfcVector3> in = curve.verts;
|
||||
|
||||
// First step: transform all vertices into the target coordinate space
|
||||
IfcMatrix4 trafo;
|
||||
|
@ -567,7 +547,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
|
||||
IfcVector3 vmin, vmax;
|
||||
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
||||
BOOST_FOREACH(IfcVector3& v,in) {
|
||||
BOOST_FOREACH(IfcVector3& v, in) {
|
||||
v *= trafo;
|
||||
|
||||
vmin = std::min(vmin, v);
|
||||
|
@ -576,14 +556,12 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
|
||||
vmax -= vmin;
|
||||
const IfcFloat diag = vmax.Length();
|
||||
|
||||
IfcVector3 min = in[0];
|
||||
dir *= IfcMatrix3(trafo);
|
||||
IfcVector3 dir = IfcMatrix3(trafo) * extrusionDir;
|
||||
|
||||
// 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 )
|
||||
std::reverse( in.begin(), in.end());
|
||||
std::reverse(in.begin(), in.end());
|
||||
|
||||
std::vector<IfcVector3> nors;
|
||||
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
||||
|
@ -591,25 +569,24 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
// Compute the normal vectors for all opening polygons as a prerequisite
|
||||
// to TryAddOpenings_Poly2Tri()
|
||||
// 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
|
||||
// doesn't matter, but we would screw up if we started with e.g. a door in between
|
||||
// two windows.
|
||||
std::sort(conv.apply_openings->begin(),conv.apply_openings->end(),
|
||||
TempOpening::DistanceSorter(min));
|
||||
std::sort(conv.apply_openings->begin(), conv.apply_openings->end(), TempOpening::DistanceSorter(in[0]));
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (bounds.verts.size() <= 2) {
|
||||
if( bounds.verts.size() <= 2 ) {
|
||||
nors.push_back(IfcVector3());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,18 +596,18 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
std::vector<IfcVector3>& out = curmesh.verts;
|
||||
|
||||
size_t sides_with_openings = 0;
|
||||
for(size_t i = 0; i < size; ++i) {
|
||||
const size_t next = (i+1)%size;
|
||||
for( size_t i = 0; i < in.size(); ++i ) {
|
||||
const size_t next = (i + 1) % in.size();
|
||||
|
||||
curmesh.vertcnt.push_back(4);
|
||||
|
||||
out.push_back(in[i]);
|
||||
out.push_back(in[next]);
|
||||
out.push_back(in[next]+dir);
|
||||
out.push_back(in[i]+dir);
|
||||
out.push_back(in[next] + dir);
|
||||
out.push_back(in[i] + dir);
|
||||
|
||||
if(openings) {
|
||||
if((in[i]-in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
||||
if( openings ) {
|
||||
if( (in[i] - in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||
++sides_with_openings;
|
||||
}
|
||||
|
||||
|
@ -639,9 +616,9 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
}
|
||||
}
|
||||
|
||||
if(openings) {
|
||||
if( openings ) {
|
||||
BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) {
|
||||
if (!opening.wallPoints.empty()) {
|
||||
if( !opening.wallPoints.empty() ) {
|
||||
IFCImporter::LogError("failed to generate all window caps");
|
||||
}
|
||||
opening.wallPoints.clear();
|
||||
|
@ -649,20 +626,21 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
}
|
||||
|
||||
size_t sides_with_v_openings = 0;
|
||||
if(has_area) {
|
||||
if( has_area ) {
|
||||
|
||||
for(size_t n = 0; n < 2; ++n) {
|
||||
for( size_t n = 0; n < 2; ++n ) {
|
||||
if( n > 0 ) {
|
||||
for(size_t i = 0; i < size; ++i )
|
||||
out.push_back(in[i]+dir);
|
||||
} else {
|
||||
for(size_t i = size; i--; )
|
||||
for( size_t i = 0; i < in.size(); ++i )
|
||||
out.push_back(in[i] + dir);
|
||||
}
|
||||
else {
|
||||
for( size_t i = in.size(); i--; )
|
||||
out.push_back(in[i]);
|
||||
}
|
||||
|
||||
curmesh.vertcnt.push_back(size);
|
||||
if(openings && size > 2) {
|
||||
if(GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) {
|
||||
curmesh.vertcnt.push_back(in.size());
|
||||
if( openings && in.size() > 2 ) {
|
||||
if( GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
|
||||
++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");
|
||||
}
|
||||
|
||||
|
@ -680,19 +658,60 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
|
|||
|
||||
// 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.
|
||||
if(collect_openings && !result.IsEmpty()) {
|
||||
if( collect_openings && !result.IsEmpty() ) {
|
||||
ai_assert(conv.collect_openings);
|
||||
boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||
profile->Swap(result);
|
||||
|
||||
boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh());
|
||||
profile2D->Swap(meshout);
|
||||
conv.collect_openings->push_back(TempOpening(&solid,dir,profile, profile2D));
|
||||
profile2D->verts.insert(profile2D->verts.end(), in.begin(), in.end());
|
||||
profile2D->vertcnt.push_back(in.size());
|
||||
conv.collect_openings->push_back(TempOpening(&solid, dir, profile, profile2D));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
|
||||
ConversionData& conv)
|
||||
|
@ -785,7 +804,7 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, unsigned int matid,
|
|||
meshtmp->RemoveDegenerates();
|
||||
|
||||
if(fix_orientation) {
|
||||
meshtmp->FixupFaceOrientation();
|
||||
// meshtmp->FixupFaceOrientation();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// skip over space and annotation nodes - usually, these have no meaning in Assimp's context
|
||||
bool skipGeometry = false;
|
||||
if(conv.settings.skipSpaceRepresentations) {
|
||||
if(const IfcSpace* const space = el.ToPtr<IfcSpace>()) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (!skipGeometry) {
|
||||
ProcessProductRepresentation(el,nd.get(),subnodes,conv);
|
||||
conv.apply_openings = conv.collect_openings = NULL;
|
||||
}
|
||||
|
||||
if (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
|
||||
{
|
||||
bool operator () (const IfcVector3& a, const IfcVector3& b)
|
||||
bool operator () (const IfcVector3& a, const IfcVector3& b) const
|
||||
{
|
||||
IfcVector3 d = a - b;
|
||||
IfcFloat eps = 1e-6;
|
||||
|
|
|
@ -277,6 +277,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix);
|
|||
|
||||
// IFCProfile.cpp
|
||||
bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
|
||||
bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
|
||||
|
||||
// IFCMaterial.cpp
|
||||
unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, assimp team
|
||||
Copyright (c) 2006-2015, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -140,6 +140,9 @@ corresponding preprocessor flag to selectively disable formats.
|
|||
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
||||
# include "OgreImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||
# include "OpenGEXImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
||||
# include "MS3DLoader.h"
|
||||
#endif
|
||||
|
@ -272,6 +275,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
|||
#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
|
||||
out.push_back( new Ogre::OgreImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_OPENGEX_IMPORTER )
|
||||
out.push_back( new OpenGEX::OpenGEXImporter() );
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
|
||||
out.push_back( new MS3DImporter());
|
||||
#endif
|
||||
|
@ -305,4 +311,4 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
|||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace Assimp {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
ObjExporter exporter(pFile, pScene);
|
||||
|
|
|
@ -203,7 +203,7 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
|||
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
|
||||
for (size_t index =0; index < MeshArray.size(); index++)
|
||||
{
|
||||
pScene->mMeshes [ index ] = MeshArray[ index ];
|
||||
pScene->mMeshes[ index ] = MeshArray[ index ];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
|||
appendChildToParentNode( pParent, pNode );
|
||||
}
|
||||
|
||||
for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
|
||||
for ( size_t i=0; i< pObject->m_Meshes.size(); i++ )
|
||||
{
|
||||
unsigned int meshId = pObject->m_Meshes[ i ];
|
||||
aiMesh *pMesh = createTopology( pModel, pObject, meshId );
|
||||
|
@ -273,16 +273,17 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Create topology data
|
||||
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex )
|
||||
unsigned int meshIndex )
|
||||
{
|
||||
// Checking preconditions
|
||||
ai_assert( NULL != pModel );
|
||||
|
||||
if( NULL == pData ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create faces
|
||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
|
||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ meshIndex ];
|
||||
if( !pObjMesh ) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -351,7 +352,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
|||
}
|
||||
|
||||
// Create mesh vertices
|
||||
createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
|
||||
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
|
||||
|
||||
return pMesh;
|
||||
}
|
||||
|
@ -362,7 +363,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
const ObjFile::Object* pCurrentObject,
|
||||
unsigned int uiMeshIndex,
|
||||
aiMesh* pMesh,
|
||||
unsigned int uiIdxCount)
|
||||
unsigned int numIndices)
|
||||
{
|
||||
// Checking preconditions
|
||||
ai_assert( NULL != pCurrentObject );
|
||||
|
@ -377,7 +378,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
return;
|
||||
|
||||
// Copy vertices of this mesh instance
|
||||
pMesh->mNumVertices = uiIdxCount;
|
||||
pMesh->mNumVertices = numIndices;
|
||||
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
||||
|
||||
// Allocate buffer for normal vectors
|
||||
|
|
|
@ -97,13 +97,15 @@ private:
|
|||
|
||||
//! \brief Creates vertices from model.
|
||||
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.
|
||||
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
|
||||
|
||||
//! \brief Material creation.
|
||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
|
||||
/// @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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Assimp {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
PlyExporter exporter(pFile, pScene, true);
|
||||
|
|
|
@ -68,6 +68,25 @@ static const aiImporterDesc desc = {
|
|||
"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
|
||||
PLYImporter::PLYImporter()
|
||||
|
@ -435,13 +454,13 @@ void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
|
|||
if (0xFFFFFFFF != aiPositions[0])
|
||||
{
|
||||
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])
|
||||
{
|
||||
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
|
||||
pvOut->push_back(vOut);
|
||||
|
@ -545,19 +564,19 @@ void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
|
|||
if (0xFFFFFFFF != aiPositions[0])
|
||||
{
|
||||
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])
|
||||
{
|
||||
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])
|
||||
{
|
||||
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
|
||||
|
@ -663,28 +682,28 @@ void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
|
|||
|
||||
if (0xFFFFFFFF != aiPositions[0])
|
||||
{
|
||||
vOut.r = NormalizeColorValue((*i).alProperties[
|
||||
aiPositions[0]].avList.front(),aiTypes[0]);
|
||||
vOut.r = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||
aiPositions[0]).avList.front(),aiTypes[0]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiPositions[1])
|
||||
{
|
||||
vOut.g = NormalizeColorValue((*i).alProperties[
|
||||
aiPositions[1]].avList.front(),aiTypes[1]);
|
||||
vOut.g = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||
aiPositions[1]).avList.front(),aiTypes[1]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiPositions[2])
|
||||
{
|
||||
vOut.b = NormalizeColorValue((*i).alProperties[
|
||||
aiPositions[2]].avList.front(),aiTypes[2]);
|
||||
vOut.b = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||
aiPositions[2]).avList.front(),aiTypes[2]);
|
||||
}
|
||||
|
||||
// assume 1.0 for the alpha channel ifit is not set
|
||||
if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
|
||||
else
|
||||
{
|
||||
vOut.a = NormalizeColorValue((*i).alProperties[
|
||||
aiPositions[3]].avList.front(),aiTypes[3]);
|
||||
vOut.a = NormalizeColorValue(GetProperty((*i).alProperties,
|
||||
aiPositions[3]).avList.front(),aiTypes[3]);
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -793,7 +812,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
|
|||
if (0xFFFFFFFF != iMaterialIndex)
|
||||
{
|
||||
sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
|
||||
(*i).alProperties[iMaterialIndex].avList.front(),eType2);
|
||||
GetProperty((*i).alProperties, iMaterialIndex).avList.front(),eType2);
|
||||
}
|
||||
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
|
||||
bool flip = false;
|
||||
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
|
||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
|
||||
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty((*i).alProperties, iProperty).avList;
|
||||
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
|
||||
|
||||
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;
|
||||
else
|
||||
{
|
||||
clrOut->r = NormalizeColorValue(avList[
|
||||
aiPositions[0]].avList.front(),aiTypes[0]);
|
||||
clrOut->r = NormalizeColorValue(GetProperty(avList,
|
||||
aiPositions[0]).avList.front(),aiTypes[0]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
|
||||
else
|
||||
{
|
||||
clrOut->g = NormalizeColorValue(avList[
|
||||
aiPositions[1]].avList.front(),aiTypes[1]);
|
||||
clrOut->g = NormalizeColorValue(GetProperty(avList,
|
||||
aiPositions[1]).avList.front(),aiTypes[1]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
|
||||
else
|
||||
{
|
||||
clrOut->b = NormalizeColorValue(avList[
|
||||
aiPositions[2]].avList.front(),aiTypes[2]);
|
||||
clrOut->b = NormalizeColorValue(GetProperty(avList,
|
||||
aiPositions[2]).avList.front(),aiTypes[2]);
|
||||
}
|
||||
|
||||
// assume 1.0 for the alpha channel ifit is not set
|
||||
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
|
||||
else
|
||||
{
|
||||
clrOut->a = NormalizeColorValue(avList[
|
||||
aiPositions[3]].avList.front(),aiTypes[3]);
|
||||
clrOut->a = NormalizeColorValue(GetProperty(avList,
|
||||
aiPositions[3]).avList.front(),aiTypes[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1048,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
|
|||
// handle phong power and shading mode
|
||||
int iMode;
|
||||
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
|
||||
// become 1, not depending on the angle), use gouraud lighting
|
||||
|
@ -1047,7 +1066,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
|
|||
|
||||
// handle opacity
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Assimp {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
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
|
||||
STLExporter exporter(pFile, pScene, true);
|
||||
|
|
|
@ -1026,7 +1026,9 @@ void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
|
|||
dest->mFlags = src->mFlags;
|
||||
|
||||
// source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
|
||||
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;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -571,6 +573,7 @@ void CatmullClarkSubdivider::InternSubdivide (
|
|||
}
|
||||
}
|
||||
}
|
||||
} // end of scope for edges, freeing its memory
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 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
|
||||
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 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
|
||||
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
|
||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||
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.
|
||||
|
@ -103,7 +109,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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
|
||||
mOutput.imbue( std::locale("C") );
|
||||
|
@ -133,7 +139,7 @@ void XFileExporter::WriteFile()
|
|||
{
|
||||
// note, that all realnumber values must be comma separated in x files
|
||||
mOutput.setf(std::ios::fixed);
|
||||
mOutput.precision(6); // precission for float
|
||||
mOutput.precision(16); // precission for double
|
||||
|
||||
// entry of writing the file
|
||||
WriteHeader();
|
||||
|
@ -155,6 +161,9 @@ void XFileExporter::WriteFile()
|
|||
// Writes the asset header
|
||||
void XFileExporter::WriteHeader()
|
||||
{
|
||||
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 << startstr << "template Frame {" << endstr;
|
||||
|
@ -305,7 +314,7 @@ void XFileExporter::WriteNode( aiNode* pNode)
|
|||
ss << "Node_" << pNode;
|
||||
pNode->mName.Set(ss.str());
|
||||
}
|
||||
mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << endstr;
|
||||
mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
|
||||
|
||||
PushTag();
|
||||
|
||||
|
@ -325,9 +334,9 @@ void XFileExporter::WriteNode( aiNode* pNode)
|
|||
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();
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ class XFileExporter
|
|||
{
|
||||
public:
|
||||
/// 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
|
||||
virtual ~XFileExporter();
|
||||
|
@ -85,7 +85,7 @@ protected:
|
|||
void WriteNode( aiNode* pNode );
|
||||
|
||||
/// 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
|
||||
void PushTag() { startstr.append( " "); }
|
||||
|
@ -99,6 +99,12 @@ public:
|
|||
|
||||
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
|
||||
void writePath(aiString path);
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ static const aiImporterDesc desc = {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
aiImporterFlags_SupportTextFlavour,
|
||||
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
@ -435,6 +435,12 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
|
|||
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
|
||||
nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
if (nd->mNumMeshes) {
|
||||
|
|
|
@ -93,6 +93,7 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
|
||||
struct TempScope
|
||||
{
|
||||
TempScope()
|
||||
|
@ -129,6 +130,16 @@ private:
|
|||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// 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.
|
||||
#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
|
|
@ -26,7 +26,7 @@
|
|||
# pragma pack(push,1)
|
||||
# define PACK_STRUCT
|
||||
#elif defined( __GNUC__ )
|
||||
# if defined(__clang__)
|
||||
# if !defined(HOST_MINGW)
|
||||
# define PACK_STRUCT __attribute__((__packed__))
|
||||
# else
|
||||
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
#include "cexport.h"
|
||||
#include <map>
|
||||
|
||||
namespace Assimp {
|
||||
class ExporterPimpl;
|
||||
|
@ -72,6 +73,9 @@ namespace Assimp {
|
|||
* #ExportToBlob is especially useful if you intend to work
|
||||
* with the data in-memory.
|
||||
*/
|
||||
|
||||
class ASSIMP_API ExportProperties;
|
||||
|
||||
class ASSIMP_API Exporter
|
||||
// TODO: causes good ol' base class has no dll interface warning
|
||||
//#ifdef __cplusplus
|
||||
|
@ -81,7 +85,7 @@ class ASSIMP_API Exporter
|
|||
public:
|
||||
|
||||
/** 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 */
|
||||
struct ExportFormatEntry
|
||||
|
@ -171,8 +175,8 @@ public:
|
|||
* Any IO handlers set via #SetIOHandler are ignored here.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene. */
|
||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
|
||||
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& 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, const ExportProperties* pProperties = NULL);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -208,8 +212,8 @@ public:
|
|||
* @return AI_SUCCESS if everything was fine.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene.*/
|
||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
|
||||
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& 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, const ExportProperties* pProperties = NULL);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -309,16 +313,188 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing )
|
||||
class ASSIMP_API ExportProperties
|
||||
{
|
||||
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
|
||||
|
|
|
@ -879,4 +879,15 @@ enum aiComponent
|
|||
|
||||
#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
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
<property name="build.dir" value="jassimp/bin" />
|
||||
<property name="dist.dir" value="dist" />
|
||||
<property name="doc.dir" value="doc" />
|
||||
<property environment="env"/>
|
||||
<property name="ndk.dir" value="${env.NDK_HOME}" />
|
||||
<property name="my.dir" value="${env.PWD}" />
|
||||
|
||||
<path id="classpath">
|
||||
</path>
|
||||
|
@ -27,6 +30,12 @@
|
|||
</javah>
|
||||
</target>
|
||||
|
||||
<target name="ndk-jni" depends="package">
|
||||
<exec executable="${ndk.dir}/ndk-build">
|
||||
<arg line="all NDK_PROJECT_PATH=${my.dir}/workspaces/Android-NDK"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="package" depends="compile">
|
||||
<jar destfile="${dist.dir}/jassimp.jar" basedir="${build.dir}">
|
||||
</jar>
|
||||
|
|
|
@ -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 ANDROID
|
||||
#include <android/log.h>
|
||||
#define lprintf(...) __android_log_print(ANDROID_LOG_VERBOSE, __func__, __VA_ARGS__)
|
||||
#else
|
||||
#define lprintf(...) printf (__VA_ARGS__)
|
||||
#endif /* ANDROID */
|
||||
#else
|
||||
#define lprintf
|
||||
#endif
|
||||
|
||||
|
||||
static bool createInstance(JNIEnv *env, const char* className, jobject& newInstance)
|
||||
{
|
||||
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);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -60,6 +65,7 @@ static bool createInstance(JNIEnv *env, const char* className, const char* signa
|
|||
}
|
||||
|
||||
newInstance = env->NewObjectA(clazz, ctr_id, params);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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");
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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");
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
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,
|
||||
const char* signature, const jvalue* params)
|
||||
const char* signature,/* const*/ jvalue* params)
|
||||
{
|
||||
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);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
if (NULL == mid)
|
||||
{
|
||||
|
@ -210,6 +221,27 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
|
|||
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);
|
||||
|
||||
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,
|
||||
const char* signature, const jvalue* params, jobject& returnValue)
|
||||
const char* signature,/* const*/ jvalue* params, jobject& returnValue)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -283,7 +315,7 @@ static bool copyBufferArray(JNIEnv *env, jobject jMesh, const char* jBufferName,
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -338,7 +370,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
/* set general mesh data in java */
|
||||
jvalue setTypesParams[1];
|
||||
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;
|
||||
}
|
||||
|
@ -380,7 +412,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
allocateBuffersParams[1].i = cMesh->mNumFaces;
|
||||
allocateBuffersParams[2].z = isPureTriangle;
|
||||
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;
|
||||
}
|
||||
|
@ -470,7 +502,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
jvalue allocateDataChannelParams[2];
|
||||
allocateDataChannelParams[0].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");
|
||||
return false;
|
||||
|
@ -491,7 +523,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
jvalue allocateDataChannelParams[2];
|
||||
allocateDataChannelParams[0].i = 1;
|
||||
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");
|
||||
return false;
|
||||
|
@ -512,7 +544,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
jvalue allocateDataChannelParams[2];
|
||||
allocateDataChannelParams[0].i = 2;
|
||||
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");
|
||||
return false;
|
||||
|
@ -535,7 +567,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
jvalue allocateDataChannelParams[2];
|
||||
allocateDataChannelParams[0].i = 3;
|
||||
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");
|
||||
return false;
|
||||
|
@ -574,7 +606,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
|
@ -671,7 +703,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapParams[0].l = jMatrixArr;
|
||||
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;
|
||||
}
|
||||
|
@ -701,6 +733,8 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
}
|
||||
}
|
||||
}
|
||||
env->DeleteLocalRef(jMeshes);
|
||||
env->DeleteLocalRef(jMesh);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -719,7 +753,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
|
|||
wrapMatParams[0].l = jMatrixArr;
|
||||
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;
|
||||
}
|
||||
|
@ -749,7 +783,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
|
|||
wrapNodeParams[2].l = jMeshrefArr;
|
||||
wrapNodeParams[3].l = jNodeName;
|
||||
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))
|
||||
{
|
||||
return false;
|
||||
|
@ -805,7 +839,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
{
|
||||
const aiMaterial* cMaterial = cScene->mMaterials[m];
|
||||
|
||||
lprintf("converting material ...\n", m);
|
||||
lprintf("converting material %d ...\n", m);
|
||||
|
||||
jobject jMaterial = NULL;
|
||||
|
||||
|
@ -842,7 +876,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
setNumberParams[0].i = ttInd;
|
||||
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;
|
||||
}
|
||||
|
@ -880,7 +914,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapColorParams[0].f = ((float*) cProperty->mData)[0];
|
||||
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
||||
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;
|
||||
}
|
||||
|
@ -905,7 +939,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
|
||||
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
|
||||
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;
|
||||
}
|
||||
|
@ -1137,7 +1171,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapColorParams[1].f = cLight->mColorDiffuse.g;
|
||||
wrapColorParams[2].f = cLight->mColorDiffuse.b;
|
||||
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;
|
||||
}
|
||||
|
@ -1146,7 +1180,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapColorParams[1].f = cLight->mColorSpecular.g;
|
||||
wrapColorParams[2].f = cLight->mColorSpecular.b;
|
||||
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;
|
||||
}
|
||||
|
@ -1155,7 +1189,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapColorParams[1].f = cLight->mColorAmbient.g;
|
||||
wrapColorParams[2].f = cLight->mColorAmbient.b;
|
||||
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;
|
||||
}
|
||||
|
@ -1167,7 +1201,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapVec3Params[1].f = cLight->mPosition.y;
|
||||
wrapVec3Params[2].f = cLight->mPosition.z;
|
||||
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;
|
||||
}
|
||||
|
@ -1176,7 +1210,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapVec3Params[1].f = cLight->mPosition.y;
|
||||
wrapVec3Params[2].f = cLight->mPosition.z;
|
||||
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;
|
||||
}
|
||||
|
@ -1242,7 +1276,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapPositionParams[1].f = cCamera->mPosition.y;
|
||||
wrapPositionParams[2].f = cCamera->mPosition.z;
|
||||
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;
|
||||
}
|
||||
|
@ -1251,7 +1285,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapPositionParams[1].f = cCamera->mUp.y;
|
||||
wrapPositionParams[2].f = cCamera->mUp.z;
|
||||
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;
|
||||
}
|
||||
|
@ -1260,7 +1294,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
|||
wrapPositionParams[1].f = cCamera->mLookAt.y;
|
||||
wrapPositionParams[2].f = cCamera->mLookAt.z;
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
(JNIEnv *env, jclass jClazz)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,23 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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
|
||||
* Method: getErrorString
|
||||
|
|
|
@ -140,13 +140,17 @@ public final class AiMesh {
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, assimp team
|
||||
Copyright (c) 2006-2015, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -68,19 +68,19 @@ import java.nio.ByteOrder;
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
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_postState = AiAnimBehavior.fromRawValue(postBehavior);
|
||||
|
||||
/* c data is padded -> 24 bytes with 20 bytes data */
|
||||
m_posKeys = ByteBuffer.allocateDirect(numPosKeys * POS_KEY_SIZE);
|
||||
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_scaleKeys = ByteBuffer.allocateDirect(numScaleKeys * 24);
|
||||
m_scaleKeys = ByteBuffer.allocateDirect(numScaleKeys * SCALE_KEY_SIZE);
|
||||
m_scaleKeys.order(ByteOrder.nativeOrder());
|
||||
}
|
||||
|
||||
|
@ -141,7 +140,7 @@ public final class AiNodeAnim {
|
|||
* Returns the buffer with position keys of this animation channel.<p>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
|
@ -249,8 +291,24 @@ public final class Jassimp {
|
|||
/* 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 {
|
||||
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"""
|
||||
|
||||
import sys, os, re
|
||||
from collections import OrderedDict
|
||||
|
||||
re_match_entity = re.compile(r"""
|
||||
ENTITY\s+(\w+)\s* # 'ENTITY foo'
|
||||
|
@ -68,8 +69,8 @@ re_match_field = re.compile(r"""
|
|||
|
||||
class Schema:
|
||||
def __init__(self):
|
||||
self.entities = {}
|
||||
self.types = {}
|
||||
self.entities = OrderedDict()
|
||||
self.types = OrderedDict()
|
||||
|
||||
class Entity:
|
||||
def __init__(self,name,parent,members):
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
IfcAnnotation
|
||||
IfcArbitraryClosedProfileDef
|
||||
IfcArbitraryOpenProfileDef
|
||||
IfcArbitraryProfileDefWithVoids
|
||||
IfcAxis1Placement
|
||||
IfcAxis2Placement
|
||||
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?
|
||||
---------------------------------------------------------------------------------
|
||||
run.py checks all model in the <root>/test/models folder and compares the result
|
||||
against a regression database provided by us (db.zip). If the test passes
|
||||
successfully, Assimp definitely WORKS perfectly on your system. A few failures
|
||||
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
|
||||
fails - this might be a sign of a recent regression in assimp's codebase.
|
||||
run.py checks all model in the <root>/test/models* folders and compares the result
|
||||
against a regression database provided with assimp (db.zip). A few failures
|
||||
are totally fine (see sections 7+). You need to worry if a huge
|
||||
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
|
||||
gross incompatibility with your system or compiler.
|
||||
|
||||
2) What do I need?
|
||||
---------------------------------------------------------------------------------
|
||||
- you need Python installed - 3.x !!
|
||||
- you need to build tools/assimp_cmd as described in the INSTALL file (
|
||||
make && make install on unixes,release-dll target with msvc).
|
||||
- You need Python installed (2.7+, 3.x). On Windows, run the scripts using "py".
|
||||
- You need to build the assimp command line tool (ASSIMP_BUILD_ASSIMP_TOOLS
|
||||
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?
|
||||
---------------------------------------------------------------------------------
|
||||
Use the following procedure:
|
||||
- verify the correctness of your assimp build - run the regression suite.
|
||||
DO NOT continue if one or more tests fail.
|
||||
- add your additional test files to <root>/test/models/<fileformat>, where
|
||||
<fileformat> is the file type (typically the file extension)
|
||||
- rebuild the regression database using gen_db.py
|
||||
- run the regression suite again - all tests should pass, including
|
||||
those for the new files.
|
||||
- Verify the correctness of your assimp build - run the regression suite.
|
||||
DO NOT continue if more tests fail than usual.
|
||||
- Add your additional test files to <root>/test/models/<fileformat>, where
|
||||
<fileformat> is the file type (typically the file extension).
|
||||
- If you test file does not meet the BSD license requirements, add it to
|
||||
<root>/test/models-nonbsd/<fileformat> so people know to be careful with it.
|
||||
- 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
|
||||
the SVN repository.
|
||||
|
||||
4) I made a change/fix/.. to a loader, how to update the database?
|
||||
4) I made a change/fix/patch to a loader, how to update the database?
|
||||
---------------------------------------------------------------------------------
|
||||
- rebuild the regression database using gen_db.py
|
||||
- run the suite - all tests should pass now. If they do not, don't continue
|
||||
- Rebuild the regression database using "gen_db.py <binary> -ixyz"
|
||||
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
|
||||
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 to the SVN repository
|
||||
|
||||
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
|
||||
<<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
|
||||
data buffers, such as vertex positions, are handled less strictly: min,max and
|
||||
average values are stored with lower precision. This takes hardware- or
|
||||
data buffers, such as vertex positions are handled less strictly: min, max and
|
||||
average values are stored with low precision. This takes hardware- or
|
||||
compiler-specific differences in floating-point computations into account.
|
||||
Generally, almost all significant regressions will be detected while the
|
||||
number of false positives is relatively low.
|
||||
|
||||
7) The test suite fails, what do do?
|
||||
---------------------------------------------------------------------------------
|
||||
Get back to ../results and check out regression_suite_failures.txt
|
||||
It contains a list of all files which failed the test ... they're copied to
|
||||
../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.
|
||||
To quickly find all all reports pertaining to tests which failed, I'd
|
||||
recommend grepping for 'but' because its a constituent of all error messages
|
||||
produced by assimp_cmd :) Error reports contain detailed information
|
||||
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.
|
||||
Get back to <root>/test/results and look at regression_suite_failures.txt.
|
||||
It contains a list of all files which failed the test. Failing dumps are copied to
|
||||
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. Grep
|
||||
for the file name in question and locate the log for the failed comparison. It
|
||||
contains a full trace of which scene elements have been compared before, which
|
||||
makes it reasonably easy to locate the offending field.
|
||||
|
||||
8) fp:fast vs fp:precise fails the test suite (same for gcc equivalents)
|
||||
---------------------------------------------------------------------------------
|
||||
As mentioned above, floating-point inaccuracies between differently optimized
|
||||
builds are not considered regressions and all float comparisons done by the test
|
||||
suite involve an epsilon. Changing floating-point optimizations can, however,
|
||||
lead to *real* changes in the output data structure, such as different number
|
||||
of vertices or faces, ... this violates one of our primary targets, that is
|
||||
produce reliable and portable output. We're working hard on removing these
|
||||
issues, but at the moment you have to live with few of them.
|
||||
|
||||
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.
|
||||
suite involve an epsilon to accomodate. However compiler settings that allow
|
||||
compilers to perform non-IEEE754 compliant optimizations can cause arbitrary
|
||||
failures in the test suite. Even if the compiler is configured to be IEE754
|
||||
comformant, there is lots of code in assimp that leaves the compiler a choice
|
||||
and different compilers make different choices (for example the precision of
|
||||
float intermediaries is implementation-specified).
|
||||
|
||||
|
||||
|
||||
|
|
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,
|
||||
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
|
||||
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.
|
||||
|
||||
-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
|
||||
for tp in settings.model_directories:
|
||||
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("Updated {0} entries".format(num))
|
||||
|
@ -172,43 +173,44 @@ def gen_db(ext_list,outfile):
|
|||
|
||||
# -------------------------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
assimp_bin_path = sys.argv[1] if len(sys.argv) > 1 else 'assimp'
|
||||
|
||||
def clean(f):
|
||||
f = f.strip("* \'")
|
||||
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)
|
||||
sys.exit(0)
|
||||
|
||||
assimp_bin_path = sys.argv[1]
|
||||
ext_list, preview, nozip = None, False, False
|
||||
for m in sys.argv[1:]:
|
||||
for m in sys.argv[2:]:
|
||||
if m[:10]=="--exclude=":
|
||||
settings.exclude_extensions += map(clean, m[10:].split(","))
|
||||
elif m[:3]=="-e=":
|
||||
settings.exclude_extensions += map(clean, m[3:].split(","))
|
||||
elif m[:2]=="-e":
|
||||
settings.exclude_extensions += map(clean, m[2:].split(","))
|
||||
elif m[:10]=="--include=":
|
||||
ext_list = m[10:].split(",")
|
||||
elif m[:3]=="-i=":
|
||||
ext_list = m[3:].split(",")
|
||||
elif m[:2]=="-i":
|
||||
ext_list = m[2:].split(",")
|
||||
elif m=="-p" or m == "--preview":
|
||||
preview = True
|
||||
elif m=="-n" or m == "--nozip":
|
||||
nozip = True
|
||||
else:
|
||||
print("Unrecognized parameter: " + m)
|
||||
sys.exit(-1)
|
||||
|
||||
outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
|
||||
if ext_list is None:
|
||||
(ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"],
|
||||
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
|
||||
ext_list = list(filter(lambda f: not f in settings.exclude_extensions,
|
||||
map(clean, ext_list)))
|
||||
|
||||
print('File extensions processed: ' + ', '.join(ext_list))
|
||||
if preview:
|
||||
print(','.join(ext_list))
|
||||
sys.exit(1)
|
||||
|
||||
extract_zip()
|
||||
|
|
|
@ -65,7 +65,7 @@ import utils
|
|||
# -------------------------------------------------------------------------------
|
||||
EXPECTED_FAILURE_NOT_MET, DATABASE_LENGTH_MISMATCH, \
|
||||
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", {
|
||||
EXPECTED_FAILURE_NOT_MET:
|
||||
|
@ -88,7 +88,10 @@ messages = collections.defaultdict(lambda: "<unknown", {
|
|||
|
||||
COMPARE_SUCCESS:
|
||||
"""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"
|
||||
|
@ -167,11 +170,11 @@ def process_dir(d, outfile_results, zipin, result):
|
|||
print("Processing directory " + d)
|
||||
for f in sorted(os.listdir(d)):
|
||||
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)
|
||||
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)
|
||||
continue
|
||||
|
||||
|
@ -190,32 +193,30 @@ def process_dir(d, outfile_results, zipin, result):
|
|||
"regression database? Use gen_db.zip to re-generate.")
|
||||
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)
|
||||
|
||||
outfile_actual = prepare_output_dir(fullpath, filehash, "ACTUAL")
|
||||
outfile_expect = prepare_output_dir(fullpath, filehash, "EXPECT")
|
||||
outfile_results.write("assimp dump "+"-"*80+"\n")
|
||||
outfile_results.flush()
|
||||
|
||||
command = [assimp_bin_path,
|
||||
"dump",
|
||||
fullpath, outfile_actual, "-b", "-s", "-l" ] +\
|
||||
pppreset.split()
|
||||
|
||||
r = subprocess.call(command, **shellparams)
|
||||
print(r)
|
||||
outfile_results.flush()
|
||||
|
||||
if r and not failure:
|
||||
result.fail(fullpath, outfile_expect, pppreset, IMPORT_FAILURE, r)
|
||||
outfile_results.write("Failed to import\n")
|
||||
continue
|
||||
elif failure and not r:
|
||||
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
|
||||
|
||||
with open(outfile_expect, "wb") as s:
|
||||
|
@ -227,21 +228,24 @@ def process_dir(d, outfile_results, zipin, result):
|
|||
except IOError:
|
||||
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):
|
||||
result.fail(fullpath, outfile_expect, pppreset, DATABASE_LENGTH_MISMATCH,
|
||||
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.flush()
|
||||
|
||||
command = [ assimp_bin_path, 'cmpdump', outfile_actual, outfile_expect ]
|
||||
if subprocess.call(command, **shellparams) != 0:
|
||||
if not failed:
|
||||
result.fail(fullpath, outfile_expect, pppreset, DATABASE_VALUE_MISMATCH)
|
||||
continue
|
||||
|
||||
result.ok(fullpath, pppreset, COMPARE_SUCCESS,
|
||||
len(input_expected))
|
||||
result.ok(fullpath, pppreset, COMPARE_SUCCESS, len(input_expected))
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
def del_folder_with_contents(folder):
|
||||
|
|
|
@ -60,9 +60,9 @@ files_to_ignore = ["pond.0.ply"]
|
|||
# File extensions are case insensitive
|
||||
# -------------------------------------------------------------------------------
|
||||
exclude_extensions = [
|
||||
".lws", ".assbin", ".assxml", ".txt", ".md",
|
||||
".assbin", ".assxml", ".txt", ".md",
|
||||
".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
|
||||
and platforms, so we implement the hashing manually.
|
||||
"""
|
||||
|
||||
file = file.lower()
|
||||
file = file.replace('\\','/')+":"+pp
|
||||
# SDBM hash
|
||||
res = 0
|
||||
for t in file:
|
||||
res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
|
||||
|
||||
# Python 2.7 normalization: strip 'L' suffix.
|
||||
return hex(res).rstrip('L')
|
||||
return '{:x}'.format(res)
|
||||
|
||||
|
||||
# vim: ai ts=4 sts=4 et sw=4
|
||||
|
|
|
@ -28,7 +28,7 @@ IF( WIN32 )
|
|||
MAIN_DEPENDENCY assimp)
|
||||
ENDIF( WIN32 )
|
||||
|
||||
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} )
|
||||
SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
|
||||
OUTPUT_NAME assimp
|
||||
)
|
||||
|
|
|
@ -140,15 +140,16 @@ public:
|
|||
if(it != history.back().second.end()) {
|
||||
++history.back().second[s];
|
||||
}
|
||||
else history.back().second[s] = 1;
|
||||
else history.back().second[s] = 0;
|
||||
|
||||
history.push_back(HistoryEntry(s,PerChunkCounter()));
|
||||
|
||||
debug_trace.push_back("PUSH " + s);
|
||||
}
|
||||
|
||||
/* leave current scope */
|
||||
void pop_elem() {
|
||||
ai_assert(history.size());
|
||||
debug_trace.push_back("POP "+ history.back().first);
|
||||
history.pop_back();
|
||||
}
|
||||
|
||||
|
@ -249,30 +250,50 @@ private:
|
|||
const char* last = history.back().first.c_str();
|
||||
std::string pad;
|
||||
|
||||
for(ChunkHistory::reverse_iterator rev = ++history.rbegin(),
|
||||
end = history.rend(); rev < end; ++rev, pad += " ")
|
||||
for(ChunkHistory::reverse_iterator rev = history.rbegin(),
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/* read from both streams simult.*/
|
||||
/* read from both streams at the same time */
|
||||
template <typename T> void read(T& filla,T& fille) {
|
||||
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)) {
|
||||
throw compare_fails_exception("Unexpected EOF reading EXPECT");
|
||||
EOFExpect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
typedef std::map<std::string,unsigned int> PerChunkCounter;
|
||||
|
@ -281,6 +302,8 @@ private:
|
|||
typedef std::deque<HistoryEntry> ChunkHistory;
|
||||
ChunkHistory history;
|
||||
|
||||
std::vector<std::string> debug_trace;
|
||||
|
||||
typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack;
|
||||
LengthStack lengths;
|
||||
|
||||
|
@ -296,10 +319,10 @@ template <> void comparer_context :: read<aiString>(aiString& filla,aiString& fi
|
|||
read(lena,lene);
|
||||
|
||||
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)) {
|
||||
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
|
||||
EOFExpect();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
|
@ -510,7 +533,7 @@ private:
|
|||
if (current.first != actual.first) {
|
||||
std::stringstream ss;
|
||||
ctx.failure((ss
|
||||
<<"Chunk lenghts do not match. EXPECT: "
|
||||
<<"Chunk lengths do not match. EXPECT: "
|
||||
<<current.second
|
||||
<<" ACTUAL: "
|
||||
<< actual.second,
|
||||
|
@ -729,7 +752,7 @@ void CompareOnTheFlyLight(comparer_context& comp) {
|
|||
const aiLightSourceType type = static_cast<aiLightSourceType>(
|
||||
comp.cmp<uint32_t>("mType"));
|
||||
|
||||
if(type==aiLightSource_DIRECTIONAL) {
|
||||
if(type!=aiLightSource_DIRECTIONAL) {
|
||||
comp.cmp<float>("mAttenuationConstant");
|
||||
comp.cmp<float>("mAttenuationLinear");
|
||||
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